【发布时间】:2019-06-05 06:31:20
【问题描述】:
我有一列包含不同长度的字符串,其中包含分隔字母数字字符串的破折号 (-)。 该字符串可能看起来像“A1-2-3”。 我需要先订购“A1”然后“2”然后“3”
我想为列实现以下顺序:
A1
A1-1-1
A1-1-2
A1-1-3
A1-2-1
A1-2-2
A1-2-3
A1-7
A2-1-1
A2-1-2
A2-1-3
A2-2-1
A2-2-2
A2-2-3
A2-10-1
A2-10-2
A2-10-3
A10-1-1
A10-1-2
A10-1-3
A10-2-1
A10-2-2
A10-2-3
我可以用以下代码分隔字符串:
declare @string varchar(max) = 'A1-2-3'
declare @first varchar(max) = SUBSTRING(@string,1,charindex('-',@string)-1)
declare @second varchar(max) = substring(@string, charindex('-',@string) + 1, charindex('-',reverse(@string))-1)
declare @third varchar(max) = right(@string,charindex('-',reverse(@string))-1)
select @first, @second, @third
根据上述逻辑,我认为我可以使用以下内容: 请注意,这只涉及带有 2 个破折号的字符串
select barcode from tabelWithBarcodes
order by
case when len(barcode) - len(replace(barcode,'-','')) = 2 then
len(SUBSTRING(barcode,1,charindex('-',barcode)-1))
end
, case when len(barcode) - len(replace(barcode,'-','')) = 2 then
SUBSTRING(barcode,1,(charindex('-',barcode)-1))
end
, case when len(barcode) - len(replace(barcode,'-','')) = 2 then
len(substring(barcode, charindex('-',barcode) + 1, charindex('-',reverse(barcode))-1))
end
, case when len(barcode) - len(replace(barcode,'-','')) = 2 then
substring(barcode, charindex('-',barcode) + 1, charindex('-',reverse(barcode))-1)
end
, case when len(barcode) - len(replace(barcode,'-','')) = 2 then
len(right(barcode,charindex('-',reverse(barcode))-1))
end
, case when len(barcode) - len(replace(barcode,'-','')) = 2 then
right(barcode,charindex('-',reverse(barcode))-1)
end
但排序不适用于字符串的第二和第三部分。 (为简单起见,我没有添加用于检查字符串中是否只有 1 个破折号或没有破折号的代码)
不确定我是否走在正确的道路上。 有人能解决这个问题吗?
【问题讨论】:
-
第 2 部分和第 3 部分是否始终为数值?最左边的字符是否总是一个字母,以及任何剩余的数字? IE。你能有像
'AB1-1-2' orA17-A4-9'`这样的值吗? -
我建议对 CTE 或子查询进行拆分,然后在外面找出正确的顺序表达式。这样你就不必每次都重复所有的解析代码。
-
然而,要回答为什么您的排序不符合您的预期,数字和字符串的排序方式不同。但是,对于数字
10 > 2,对于字符串'2' > '10'。字符串按其字符从左到右的顺序排列。'2' > '1'因此'2'的值比'10'的值“更大”。 -
你的数据没有被规范化,至少在每个数据点可能传达几条排序信息的意义上。如果您确实长期需要这种方式排序,那么我建议将每个数字存储在单独的列中。
-
@Larnu。是的,我也可以得到“AB1-2-E1”。
标签: sql sql-server tsql sorting