嗨我有一个有趣的问题,我在表中有大约1500条记录。我需要排序的列的格式是
String 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 :(得分:0)
试试这个:
SELECT column
FROM table
ORDER BY CASE WHEN SUBSTRING(column,LEN(column)-1,1) = '.'
THEN 0
ELSE 1
END, column
这将在排序中首先将.
的任何字符串放在倒数第二位置。
编辑:
第二个想法是,这不会与领先的' AB' ACA'试试这个:
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
基本上,这是一种通过计算每种条件来强制进行分层排序的手动方式。
答案 1 :(得分:0)
您需要对第一个文本标记进行排序,然后对第二个文本标记(不是数字,它是包含一些数字的字符串)进行排序,然后可选地对任何剩余文本进行排序。
要正确排序第二个令牌(就像我假设的版本号一样),您可以使用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
答案 2 :(得分:0)
添加相同长度的文字
SELECT column
FROM table
ORDER BY left(column + replicate('*', 100500), 100500)
答案 3 :(得分: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