Упорядочить буквенно-цифровые значения по числовой части

#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 Смотрите мое последнее редактирование.