#sql-server
#sql-сервер
Вопрос:
У меня есть таблица с одним столбцом со следующими значениями.
|TestId|
--------
| F1 |
| F2 |
| F3 |
| A62 |
| F9 |
| DP45 |
| CAP78|
| F89 |
| F34 |
| F43 |
Мне нужно упорядочить их на основе их числовых частей. Итак, в основном мне нужно получить
F1, F2, F3,F9, F34, F43, DP45, A62, CAP78, F89
Я попробовал следующий запрос, но получил неправильные результаты.
SELECT [TestId] FROM TestingOrder
ORDER BY LEN(TestId),TestId
Я получаю F1, F2, F3, F9, A62, F34, F43, F89, DP45, CAP78, чего я не хочу.
Как мне это исправить, чтобы получить необходимый порядок?
РЕДАКТИРОВАТЬ: предоставленный ответ работает, если нет повторяющихся значений. Однако сбой при наличии повторяющихся значений
Например :
|TestId|
--------
| F1 |
| F2 |
| F3 |
| A62 |
| F9 |
| DP45 |
| CAP78|
| F89 |
| F34 |
| F43 |
| F1 |
| F3 |
| F89 |
| F34 |
Я изменил ответ на это
select TestId FROM
(SELECT DISTINCT TestId From TestingOrder) A
cross apply
( values ( convert(int,(substring(TestId, patindex('%[0-9]%', TestId), len(TestId))))) )tt(nos)
order by nos;
Результат изменяется на F1, F2, F3, F34, F43, DP45, A62, CAP78, F89, F9
Комментарии:
1. Порядок буквенно-цифровых значений сильно отличается от порядка чисел. С числами оператор
9 < 10
имеет значение true, но со строкой оператор'9' < '10'
имеет значение false. Если упорядочение действительно важно (и вы не хотите больших накладных расходов, какPATINDEX
могло бы быть), тогда подумайте о том, чтобы сделать ваш столбец ID фиксированной ширины, с начальными 0 в числовой части (если ширина альфа-части фиксирована), или разделить идентификатор на 2 столбца (альфа и числовой), с сохраненным вычисляемым столбцом для полного значения.
Ответ №1:
Вы можете использовать использовать patindex()
:
select distinct t.*
from TestingOrder t cross apply
( values ( convert(int, substring(TestId, patindex('%[0-9]%', TestId), len(TestId))))
) tt(nos)
order by tt.nos;
Комментарии:
1. Это помогает. Но что, если для ex. 2 значений F1 существует несколько значений, и мне придется группировать по, а затем перекрестно применять? Я не хочу, чтобы он отображался несколько раз
2. @TheFallenOne Использовать ‘distinct’
3. @GenWan Смотрите мое последнее редактирование.