简体   繁体   English

SQL对数字和字符串排序

[英]SQL Sorting numeric and string

Hi I have interesting problem, I have about 1500 records within a table. 嗨,我有一个有趣的问题,我在一个表中大约有1500条记录。 the format of column I need to sort against is 我需要针对的列格式为

String Number.number.(optional number) (optional string) 字符串Number.number。(可选数字)(可选字符串)

In reality this could look like this: 实际上,这可能是这样的:

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

I need a way to sort these so that instead of 我需要一种对这些进行排序的方法,而不是

AB 2.10.19
AB 2.10.2
AB 2.10.20 (I)

I get this 我明白了

AB 2.10.2
AB 2.10.19
AB 2.10.20 (I)

Because of the lack of standard formatting I'm at a loss as to how I can sort this via SQL. 由于缺乏标准格式,我对如何通过SQL进行排序感到困惑。

I'm at the point of just manually identifying a new int column to denote the sorting value, unless anyone has any suggestion? 我只是手动识别一个新的int列来表示排序值,除非有人有任何建议?

I'm using SQL Server 2008 R2 我正在使用SQL Server 2008 R2

Try this: 尝试这个:

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

This will put any strings that have a . 这将放置任何带有的字符串. in the second to last position first in the ordering. 排在倒数第二的位置。

Edit: 编辑:

On second thought, this won't work with the leading 'AB', 'ACA' etc. Try this instead: 再三考虑,这不适用于前导的“ 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: EDIT2:

To also compensate for the second numeric set, use this: 要还补偿第二个数字集,请使用以下命令:

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

Basically, this is a manual way to force hierarchical ordering by accounting for each condition. 基本上,这是一种通过考虑每个条件来强制进行分层排序的手动方法。

You would need to sort on the first text token, then on the second text token (which is not a number, its a string comprising some numbers) then optionally on any remaining text. 您将需要对第一个文本标记排序,然后对第二个文本标记(不是数字,其字符串包含一些数字)进行排序,然后对剩余的文本进行排序。

To make the 2nd token sort correctly (like a version number I presume) you can use a hierarchyid: 要正确地对第二个令牌进行排序(例如我假设的版本号),可以使用architectureid:

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

add text for the same length 添加相同长度的文本

SELECT   column
FROM     table
ORDER BY left(column + replicate('*', 100500), 100500)
--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 样本演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM