2012-07-15 23 views
28

làm tiêu đề tiểu bang:Thứ tự SQLite Bằng chuỗi có chứa số bắt đầu bằng 0

Tôi có một truy vấn chọn, mà tôi đang cố gắng "sắp xếp theo" một trường chứa số, điều này là số thực sự các chuỗi bắt đầu bằng 0, do đó, "thứ tự bằng" đang thực hiện việc này ...

... 
10 
11 
12 
01 
02 
03 
... 

Bất kỳ suy nghĩ nào?

EDIT: nếu tôi làm điều này: "... ORDER BY (trường + 1)" Tôi có thể giải quyết vấn đề này, bởi vì bằng cách nào đó chuỗi nội bộ được chuyển đổi thành số nguyên. Đây có phải là một cách để "chính thức" chuyển đổi nó như atoi của C?

+0

Bạn nhận được kết quả như thế nào? Bạn có chắc chắn các chuỗi chỉ có các số 0 đứng đầu hoặc là các khoảng trống dẫn đầu liên quan không? –

+0

Chuỗi không có không gian hàng đầu. Tôi đã cố gắng tìm một cách để sắp xếp các chuỗi chứa số (1,2,3 ..., 10,11,12) mà không có chúng được sắp xếp theo thời trang 1,10,2,3,4,5. Tôi nối thêm bằng tay 0 hàng đầu, tôi đã thử với không gian quá, nhưng tôi thấy bây giờ đúc cột để INTEGER là điều thông minh nhất để làm ở nơi đầu tiên. –

+2

Nhưng ''01'' nên đến trước' 10'' khi chúng được sắp xếp thành chuỗi, do đó sự tò mò của tôi. Hay bạn đang nói rằng bạn thực sự có ''1'' hơn là' '01'' trong cơ sở dữ liệu? –

Trả lời

57

Bạn có thể sử dụng CASThttp://www.sqlite.org/lang_expr.html#castexpr bỏ các biểu thức để một Integer.

sqlite> CREATE TABLE T (value VARCHAR(2)); 
sqlite> INSERT INTO T (value) VALUES ('10'); 
sqlite> INSERT INTO T (value) VALUES ('11'); 
sqlite> INSERT INTO T (value) VALUES ('12');  
sqlite> INSERT INTO T (value) VALUES ('01'); 
sqlite> INSERT INTO T (value) VALUES ('02'); 
sqlite> INSERT INTO T (value) VALUES ('03'); 
sqlite> SELECT * FROM T ORDER BY CAST(value AS INTEGER); 
01 
02 
03 
10 
11 
12 
sqlite> 

nếu tôi làm điều này: "... ORDER BY (lĩnh vực + 1)" Tôi có thể workaround này, bởi vì bằng cách nào đó chuỗi được nội được chuyển đổi để nguyên. Là một cách để "chính thức" chuyển đổi nó như atoi của C?

Điều đó thật thú vị, mặc dù tôi không biết số lượng DBMS hỗ trợ hoạt động như vậy trong trường hợp bạn cần sử dụng hệ thống khác không hỗ trợ nó, chưa kể bạn đang thêm một hoạt động phụ, có thể ảnh hưởng đến hiệu suất, mặc dù bạn cũng làm ORDER BY (field + 0) Im này sẽ điều tra việc thực hiện

lấy từ các tài liệu sqlite3:

một biểu CAST được sử dụng để chuyển đổi các giá trị của để một lớp lưu trữ khác theo cách tương tự với c sự đảo ngược diễn ra khi một ái lực cột được áp dụng cho một giá trị. Áp dụng một biểu thức CAST khác với ứng dụng của một cột affinity, như với một biểu thức CAST chuyển đổi lớp lưu trữ được buộc ngay cả khi nó là lossy và không thể đảo ngược.

4,0 Các nhà khai thác
Tất cả các nhà khai thác toán học (+, -, *, /,%, < <, >>, &, và |) đúc cả hai toán hạng với lớp lưu trữ NUMERIC trước khi được thực hiện. Các diễn viên được thực hiện thông qua ngay cả khi nó là lossy và không thể đảo ngược. Toán hạng NULL trên toán tử toán học mang lại kết quả NULL. Toán hạng trên toán tử toán học không nhìn theo bất kỳ cách nào bằng số và không phải là NULL được chuyển thành 0 hoặc 0.0.

Tôi đã curios vì vậy tôi chạy một số tiêu chuẩn:

>>> setup = """ 
... import sqlite3 
... import timeit 
... 
... conn = sqlite3.connect(':memory:') 
... c = conn.cursor() 
... c.execute('CREATE TABLE T (value int)') 
... for index in range(4000000, 0, -1): 
...  _ = c.execute('INSERT INTO T (value) VALUES (%i)' % index) 
... conn.commit() 
... """ 
>>> 
>>> cast_conv = "result = c.execute('SELECT * FROM T ORDER BY CAST(value AS INTEGER)')" 
>>> cast_affinity = "result = c.execute('SELECT * FROM T ORDER BY (value + 0)')" 
>>> timeit.Timer(cast_conv, setup).timeit(number = 1) 
18.145697116851807 
>>> timeit.Timer(cast_affinity, setup).timeit(number = 1) 
18.259973049163818 
>>> 

Như chúng ta có thể thấy nó chậm hơn một chút mặc dù không nhiều, thú vị.

+0

+1 cảm ơn vì thí nghiệm nhỏ –

+1

ど う い た し ま し て, không sao, cập nhật câu trả lời của tôi. –

+0

cảm ơn điểm chuẩn! Có lẽ toán hạng +0 được tối ưu hóa trước khi được thực thi, nếu đúng như vậy, +1 hoặc + ngẫu nhiên chắc chắn sẽ dẫn đến truy vấn chậm hơn. –

24

Bạn có thể sử dụng CAST:

ORDER BY CAST(columnname AS INTEGER) 
+0

Đây có phải là định dạng đúng ORDER BY CAST (cột tên AS INTEGER) = '01 ' – sherin

+0

Chúng tôi có một người chiến thắng - cảm ơn! – Rob

2

Trong ListView với trình tải con trỏ!

String projection= some string column; 
String selection= need to select; 

String sort="CAST ("+ YOUR_COLUMN_NAME + " AS INTEGER)"; 

CursorLoader(getActivity(), Table.CONTENT_URI, projection, selection, selectionArgs, sort); 
0

Nhờ Skinnynerd. với Kotlin, CAST đã làm việc như sau: CAST khắc phục các vấn đề ưu tiên 9 trên 10 HOẶC 22 trên 206.

định nghĩa biến toàn cầu để thay đổi sau theo yêu cầu, và sau đó cắm nó trong truy vấn:

var SortOrder:String?=null 

để thay đổi việc sử dụng theo thứ tự:

Đối với hậu duệ:

SortOrder = "CAST(MyNumber AS INTEGER)" + " DESC" 

(từ cao nhất đến thấp nhất)

Để tăng dần:

SortOrder = "CAST(MyNumber AS INTEGER)" + " ASC" 

(từ thấp nhất đến cao nhất)

Các vấn đề liên quan