MySQL « Сортировка чисел в текстовом поле

Как в MySQL правильно отсортировать числа разделённые точкой в текстовом поле?

Имеется:
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .sql.geshi_code {font-family:monospace;} .sql.geshi_code .imp {font-weight: bold; color: red;} .sql.geshi_code .kw1 {color: #993333; font-weight: bold;} .sql.geshi_code .co1 {color: #808080; font-style: italic;} .sql.geshi_code .co2 {color: #808080; font-style: italic;} .sql.geshi_code .coMULTI {color: #808080; font-style: italic;} .sql.geshi_code .es0 {color: #000099; font-weight: bold;} .sql.geshi_code .br0 {color: #66cc66;} .sql.geshi_code .sy0 {color: #66cc66;} .sql.geshi_code .st0 {color: #ff0000;} .sql.geshi_code .nu0 {color: #cc66cc;} .sql.geshi_code span.xtra { display:block; }

mysql> SELECT * FROM test;
+------+
| num  |
+------+
| 1.1  |
| 1.10 |
| 1.2  |
| 1.3  |
+------+
4 rows IN SET (0.00 sec)
 


Надо:
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .sql.geshi_code {font-family:monospace;} .sql.geshi_code .imp {font-weight: bold; color: red;} .sql.geshi_code .kw1 {color: #993333; font-weight: bold;} .sql.geshi_code .co1 {color: #808080; font-style: italic;} .sql.geshi_code .co2 {color: #808080; font-style: italic;} .sql.geshi_code .coMULTI {color: #808080; font-style: italic;} .sql.geshi_code .es0 {color: #000099; font-weight: bold;} .sql.geshi_code .br0 {color: #66cc66;} .sql.geshi_code .sy0 {color: #66cc66;} .sql.geshi_code .st0 {color: #ff0000;} .sql.geshi_code .nu0 {color: #cc66cc;} .sql.geshi_code span.xtra { display:block; }

+------+
| num  |
+------+
| 1.1  |
| 1.2  |
| 1.3  |
| 1.10 |
+------+
 


а так же пробовал:
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .sql.geshi_code {font-family:monospace;} .sql.geshi_code .imp {font-weight: bold; color: red;} .sql.geshi_code .kw1 {color: #993333; font-weight: bold;} .sql.geshi_code .co1 {color: #808080; font-style: italic;} .sql.geshi_code .co2 {color: #808080; font-style: italic;} .sql.geshi_code .coMULTI {color: #808080; font-style: italic;} .sql.geshi_code .es0 {color: #000099; font-weight: bold;} .sql.geshi_code .br0 {color: #66cc66;} .sql.geshi_code .sy0 {color: #66cc66;} .sql.geshi_code .st0 {color: #ff0000;} .sql.geshi_code .nu0 {color: #cc66cc;} .sql.geshi_code span.xtra { display:block; }

mysql> SELECT * FROM test ORDER BY cast(num AS signed);
+------+
| num  |
+------+
| 1.1  |
| 1.2  |
| 1.10 |
| 1.3  |
+------+
4 rows IN SET, 4 warnings (0.00 sec)
 

cast(num as signed) как-то непредсказуемо работает, то сортирует нормально (чаще всего когда только уникальные записи), то сортирует не понятно как. Может ошибся в команде?

Каким способов отсорировать?

1 ответов


Если это продолжение разговоров:
Проектирование-базы-данных-для-древовидных-комментариев и Индексы-в-базе-данных
То кто заставляет хранить в текстовом поле цифры?
Храни буквы!
На вычисление нового идентификатора надо затратить на несколько порядков меньше ресурсов, чем на сортировку преобразованиями.


Не к целому надо приводить строку, а к десятичному числу, например:
SELECT * FROM test ORDER BY CONVERT(num,DECIMAL(5,2))


Еще вариант - хранить не "1.1", а значения с ведущими нулями: "001.001", "001.002.001" и т.д Тогда сортировка по текстовому полю будет давать правильную последовательность


Функция cast(field as signed) приводит значение к целому числу. Поэтому все значения в данной таблице будут приведены к 1, а дальше сортировка, скорее всего, в естественном порядке (как записано в таблице). Если Вам нужно отсортировать сначала по числу до точки, а потом по числу после, то решение дано в ответе dm.CaT. Добавлю только, что это "дорогой" вариант запроса - не получится использовать индексы, а значит, все будет тормозить. Я бы добавил в таблицу две колонки, в которые разделил бы значения по точке, построил бы индекс и уже сортировал бы. А на insert и update повесил бы триггер, который бы разделял новые или измененные значения.

Если Вам нужно отсортировать так, как будто в колонке стоят дробные числа, то

SELECT * FROM test ORDER BY (num -0.0);

У вас два числа в каждой строке. Числа разделены точкой. Вы преобразуете два числа, разделённые точкой к одному и сортируете. Это неверно. Вам необходимо сортировать по двум подстрокам - до точки и после точки, приводя их по отдельности к числу.

UPDATE
Пример:


SELECT
    *
FROM
    test
ORDER BY
    CAST(SUBSTRING_INDEX(num, '.', 1) AS signed),
    CAST(SUBSTRING_INDEX(num, '.', -1) AS signed)
 
Описание функции: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_substring-index.
Как-то так.