2016-06-09 2 views
2

Привет У меня есть интересная проблема, у меня около 1500 записей в таблице. формат столбца мне нужно сортировать против являетсяSQL Сортировка чисел и строк

Строка Number.number (дополнительный номер) (необязательная строка)

В действительности это может выглядеть следующим образом:.

AB 2.10.19 
AB 2.10.2 
AB 2.10.20 (I) 
ACA 1.1 
ACA 1.9 (a) V 

Мне нужен способ сортировать их, так что вместо

AB 2.10.19 
AB 2.10.2 
AB 2.10.20 (I) 

Я получаю

AB 2.10.2 
AB 2.10.19 
AB 2.10.20 (I) 

Из-за отсутствия стандартного форматирования я не понимаю, как я могу сортировать это через SQL.

Я собираюсь просто вручную идентифицировать новый столбец int, чтобы обозначить значение сортировки, если у кого-нибудь не было никаких предложений?

Я использую SQL Server 2008 R2

+0

Если ваша строка всегда равна 3 числам, разделенным периодом, вы можете анализировать ее с использованием периода в качестве разделителя, отбрасывать на целое и сортировать на основе результата. –

+0

, к сожалению, нет, это может быть AB 1.1 или AB 1.1.1 или AB 1 – Andyww

ответ

0

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

SELECT column 
FROM  table 
ORDER BY CASE WHEN SUBSTRING(column,LEN(column)-1,1) = '.' 
       THEN 0 
       ELSE 1 
       END, column 

Это поместит все строки, которые имеют в второй . в последнюю позицию первого в упорядочении.

Edit:

На второй мысли, это не будет работать с ведущим 'AB', 'АС' и т.д. Попробуйте вместо этого:

SELECT column 
FROM  table 
ORDER BY SUBSTRING(column,1,2), --This will deal with leading letters up to 2 chars 
     CASE WHEN SUBSTRING(column,LEN(column)-1,1) = '.' 
       THEN 0 
       ELSE 1 
       END, 
     Column 

edit2:

Чтобы компенсировать второй цифровой набор, используйте это:

SELECT column 
FROM  table 
ORDER BY substring(column,1,2), 
CASE WHEN substring(column,charindex('.',column) + 2,1) = '.' and substring(column,len(column)-1,1) = '.' THEN 0 
    WHEN substring(column,charindex('.',column) + 2,1) = '.' and substring(column,len(column)-1,1) <> '.' THEN 1 
    WHEN substring(column,charindex('.',column) + 2,1) <> '.' and substring(column,len(column)-1,1) = '.' THEN 2 
ELSE 3 END, column 

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

+0

Спасибо, что почти там, но его переместил сортировки проблема второго числа, т.е. AB 2.1.4 AB 2.1.5 AB 2.10.1 AB 2.10.2 AB 2.2.1 – Andyww

+0

Хм .. Это будет более сложной задачей. –

+0

Это также происходит в первом сете? то есть. AB 2.1.1, AB 20.1.1 –

0

Вам нужно будет отсортировать по первому текстовому токену, а затем по второму текстовому токену (который не является числом, его строка содержит некоторые номера), а затем необязательно на любой оставшийся текст.

Для того, чтобы 2-й маркер вроде правильно (например, номер версии, я предполагаю), вы можете использовать hierarchyid` в:

with t(f) as (
    select 'AB 2.10.19' union all 
    select 'AB 2.10.2' union all 
    select 'AB 2.10.20 (I)' union all 
    select 'AB 2.10.20 (a) Z' union all 
    select 'AB 2.10.21 (a)' union all 
    select 'ACA 1.1' union all 
    select 'ACA 1.9 (a) V' union all 
    select 'AB 4.1' 
) 

select * from t 
order by 
    left(f, charindex(' ', f) - 1), 
    cast('/' + replace(substring(f, charindex(' ', f) + 1, patindex('%[0-9] %', f + ' ') - charindex(' ', f)) , '.', '/') + '/' as hierarchyid), 
    substring(f, patindex('%[0-9] %', f + ' ') + 1, len(f)) 

f 
---------------- 
AB 2.10.2 
AB 2.10.19 
AB 2.10.20 (a) Z 
AB 2.10.20 (I) 
AB 2.10.21 (a) 
AB 4.1 
ACA 1.1 
ACA 1.9 (a) V 
+0

возникла ошибка: Microsoft.SqlServer.Types.HierarchyIdException: 24001: SqlHierarchyId.Parse не удалось, поскольку входная строка '/ 1/1/4-2 /' не является допустимым строковым представлением узла SqlHierarchyId. – Andyww

+1

Вы не упомянули дефис ... –

0

добавить текст для той же длины

SELECT column 
FROM  table 
ORDER BY left(column + replicate('*', 100500), 100500) 
0
--get the start and end position of numeric in the string 
with numformat as 
(select val,patindex('%[0-9]%',val) strtnum,len(val)-patindex('%[0-9]%',reverse(val))+1 endnum 
from t 
where patindex('%[0-9]%',val) > 0) --where condition added to exclude records with no numeric part in them 
--get the substring based on the previously calculated start and end positions 
,substrng_to_sort_on as 
(select val, substring(val,strtnum,endnum-strtnum+1) as sub from numformat) 
--Final query to sort based on the 1st,2nd and the optional 3rd numbers in the string 
select val 
from substrng_to_sort_on 
order by 
cast(substring(sub,1,charindex('.',sub)-1) as numeric), --1st number in the string 
cast(substring(sub,charindex('.',sub)+1,charindex('.',reverse(sub))) as numeric), --second number in the string 
cast(reverse(substring(reverse(sub),1,charindex('.',reverse(sub))-1)) as numeric) --third number in the string 

Sample demo

+0

Это дало мне a: Неверный параметр длины передан функции LEFT или SUBSTRING. – Andyww

+0

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

+0

см. Отредактированную версию, которая исключает строки без числовой части. –

Смежные вопросы