Порядок SQLite по строке, содержащей число, начинающееся с 0

как говорится в заголовке:

У меня есть запрос select, который я пытаюсь "заказать по" полю, содержащему числа, дело в том, что эти числа действительно являются строками, начинающимися с 0s, поэтому "заказать по" делает это...

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

какие мысли?

EDIT: если я это сделаю:"...ORDER BY (field+1)" я могу обойти это, потому что каким-то образом строка внутренне преобразуется в целое число. Это способ "официально" преобразовать его, как atoi C?

4 ответов


можно использовать CAST http://www.sqlite.org/lang_expr.html#castexpr для приведения выражения к целому числу.

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>

если я сделаю это: "...ORDER BY (field+1)" я могу обойти это, потому что каким-то образом строка внутренне преобразуется в целое число. Является ли способ "официально" преобразовать его, как atoi C?

Ну, это интересно, хотя я не знаю, сколько DBMS поддержка такой операции, поэтому я не рекомендую его просто если вам когда-либо понадобится использовать другую систему, которая не поддерживает ее, не говоря уже о том, что вы добавляете дополнительную операцию, которая может повлиять на производительность, хотя вы также делаете это ORDER BY (field + 0) Я собираюсь исследовать производительность

взято из документов sqlite3:

выражение CAST используется для преобразования значения в другой класс хранения аналогично преобразованию, которое происходит, когда аффинной колонки применяется к стоимости. Применение выражения приведения отличается от применения сродства столбцов, так как с выражением приведения преобразование класса хранения принудительно, даже если оно с потерями и irrreversible.

4.0 операторов
Все математические операторы (+, -, *, /, %, >, &, и|) перед выполнением приведите оба операнда в числовой класс хранения. Бросание осуществляется, даже если оно с потерями и необратимо. Нулевой операнд математического оператора дает NULL результат. Операнд математического оператора, который никоим образом не выглядит числовым и не является нулевым, преобразуется в 0 или 0.0.

Я был диковинками, поэтому я запустил некоторые тесты:

>>> 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
>>>

как мы видим, это немного медленнее, хотя и не намного, интересно.


можно использовать CAST:

ORDER BY CAST(columnname AS INTEGER)

в ListView с загрузчиком курсоров!

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);

спасибо Skinnynerd. с Kotlin, бросание работало следующим образом: CAST исправить проблемы приоритизации 9 над 10 или 22 над 206.

определите глобальную переменную для изменения позже по требованию, а затем подключите ее к запросу:

var SortOrder:String?=null

изменить порядок использования:

для потомков:

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

(от самого высокого до самого низкого)

по возрастанию:

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

(от самого низкого до самого высокого)