2011-01-14 7 views
3

У меня есть столбец типа строка, которая содержит значения в строках, как:ORDER BY в SQL

1-1 
1-5 
1-14 
1-7 
1-3 

Теперь, если я использую ORDER BY на этой колонке я получаю заказ, как:

1-1 
1-14 
1-3 
1-5 
1-7 

что бы правильный способ заказать его как 1-1, 1-3, 1-5,1-7,1-14

Спасибо за ваше время

+0

Существует нет простого способа с этими данными, как есть. Можете ли вы изменить схему для хранения данных по-другому? – Mark

+0

Является ли «1-» одинаковым для всех полей, или у вас также есть «2-», «3-» и «10-»? Действительно ли эти поля даты (месяц и день)? Выходит ли «1-31» до или после «2-1»? – rajah9

+0

@Mark Cant меняет схему, к сожалению. @ rajah9 это не даты, они какие-то коды. – Adnan

ответ

7

Вы можете переименовать «1-1» в «1-01»

+0

Или переименуйте 1-1 до 0001-0001, чтобы быть в безопасности. ;) – WCWedin

+0

отличная идея. – Adnan

+0

Ведущие нули могут быть удалены при форматировании в переднем конце, если необходимо. Гораздо проще, если сделать так: :) – onedaywhen

2

Попробуйте это:

SELECT * FROM 
(
SELECT '1-1' Id 
UNION 
SELECT '1-5' Id 
UNION 
SELECT '1-14' Id 
UNION 
SELECT '1-7' Id 
UNION 
SELECT '1-3' Id 
) a 
ORDER BY CAST(REPLACE(Id, '-', '') AS UNSIGNED) 
+0

Приятный подход, но вы получите проблемы с 2-1 меньше 1-11. вам придется разделить, бросить оба и упорядочить по первому значению, второе значение – magnattic

+0

Это положило бы '11-3' до' 1-14'. – Quassnoi

1

Есть ли возможность разделить столбец в 2-х отдельных столбцах и CONCAT два вместе после сортировки их по отдельности ?

Проблема в том, что ваша колонка сортируется как строки не как целые числа.

5

Правильный способ - хранить их как целые числа в разных столбцах.

0

Вы можете использовать что-то вроде (если первая буква Безразлично-т РАЗНИЦА)

заказ по CAST (подстроку (поле, CHARINDEX (поле, '-', 0) +1, LEN (поле) +1), как целое)

Не очень красиво, хотя ..

10

Если предположить, что первый символ может также меняться:

order by convert(substr(my_field, 1, locate(my_field, '-') - 1) as int), 
     convert(substr(my_field, locate(my_field, '-') + 1) as int) 
+3

+1. Это правильный ответ на поставленный вопрос. Тем не менее, изменение схемы может быть лучшим решением. – WCWedin

0
SELECT * 
FROM (
     SELECT '1-1' Id 
     UNION ALL 
     SELECT '1-5' Id 
     UNION ALL 
     SELECT '1-14' Id 
     UNION ALL 
     SELECT '1-7' Id 
     UNION ALL 
     SELECT '1-3' Id 
     UNION ALL 
     SELECT '10-4' Id 
     ) a 
ORDER BY 
     CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(id, '-', -2), '-', 1) AS UNSIGNED), 
     CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(id, '-', -1), '-', 1) AS UNSIGNED) 
1

Если абсолютно невозможно внести какие-либо изменения в структуру, я бы сказал, что метод Карла Манастера лучше всего. Тем не менее, это будет работать медленно на больших наборах данных.

Вы также можете попробовать, чтобы добавить столбец «сортировки» (и индекс его), то каждый раз, когда новый код добавляется вы можете вычислить это значение, например:

1-5 становится 1000 + 5 = 1005 1-14 становится 1000 + 14 = 1014

и сохраните его в этом столбце. Это будет работать намного быстрее. Вы также можете написать простой триггер, чтобы это значение сортировки было рассчитано автоматически.