我正在尝试对varchar列A进行排序,其中包含如下数据:
A.1) NULL
A.1.xc) 1131820
B.1) NULL
B.1.xc) 1131822
C.1) NULL
C.1.xc) 131824
C.2) (CE) NULL
C.2) (NRML) NULL
C.2.xc) 131826
C.2.xc) 132152
C.3) NULL
C.3.a) 131828
C.3.a.xc) 131830
C.3.xc) 131828
C.4) NULL
C.4.a) 131838
C.4.a.xc) 131840
C.4.xc) 131838
D.1) NULL
D.1) NULL
D.1) NULL
D.1) NULL
D.1) NULL
D.1) NULL
D.1) NULL
D.1) NULL
D.1) NULL
D.1) NULL
D.1) NULL
D.1) NULL
D.1) NULL
D.1) NULL
D.1) NULL
D.1) NULL
D.1.xc) 16131842
D.1.xc) 15131842
D.1.xc) 14131842
D.1.xc) 13131842
D.1.xc) 12131842
D.1.xc) 11131842
D.1.xc) 10131842
D.1.xc) 9131842
D.1.xc) 8131842
D.1.xc) 7131842
D.1.xc) 6131842
D.1.xc) 5131842
D.1.xc) 4131842
D.1.xc) 1131842
D.1.xc) 3131842
D.1.xc) 2131842
D.2) NULL
D.2.xc) 132124
D.3) NULL
D.3.xc) 132126
D.4) NULL
D.4.xc) 1132156
D.5) (NRML) NULL
D.5.xc) 132158
E.1) NULL
E.1.xc) 132138
E.10) NULL
E.10.xc) 131932
E.10.xf) 131932
E.10.xl) 131932
E.11) (NRML) NULL
E.11.xc) 131939
E.11.xf) 131939
E.11.xl 131939
E.12.a) NULL
E.12.a.xc) 131965
E.12.a.xl) 131965
E.13) NULL
E.13.a) 131988
E.13.a.xc) 131990
E.13.xc) 131988
E.14) NULL
E.14.xc) 131994
E.14.xl) 131994
E.15) NULL
E.15.xc) 132012
E.16) NULL
E.16.xc) 132014
E.17.a) (ALLFNDS) NULL
E.17.a.xc) 132016
E.17.a.xf) 132016
E.18) NULL
E.18.xc) 132022
E.2) NULL
E.2.xc) 131844
E.3) NULL
E.3.xc) 131850
E.4) NULL
E.4.xc) 131856
E.5) NULL
E.5.xc) 131862
E.6) NULL
E.6.xc) 131868
E.7) NULL
E.7.a) 131874
E.7.a.xc) 131876
E.7.b) 131874
E.7.b.i) 131878
E.7.b.i.xc) 131886
E.7.b.xc) 131878
E.7.xc) 131874
E.8) (NRML) NULL
E.8.xc) 131890
E.9) (NRML) NULL
E.9.a) 131908
E.9.a.xc) 131910
E.9.a.xf) 131910
E.9.a.xl) 131910
E.9.xc) 131908
我使用以下查询对列进行排序
Select A,Bfrom ABCD where id =18613
order by A
现在这个查询给我的问题是E.1.xc),我期待E.2)但它正在返回我E.10)等等。
A列是varchar列。
我也尝试了这个查询,但没有运气
SELECT
CASE
WHEN ISNUMERIC(A)=1
THEN CAST(A as int)
WHEN PATINDEX('%[^0-9]%',A) > 1
THEN CAST(
LEFT(
A,
PATINDEX('%[^0-9]%',A) - 1
) as int)
ELSE 2147483648
END,
CASE
WHEN ISNUMERIC(A)=1
THEN NULL
WHEN PATINDEX('%[^0-9]%',A) > 1
THEN SUBSTRING(
A,
PATINDEX('%[^0-9]%',A) ,
50
)
ELSE A
END
from ABCD where id=18613 order by A
另外需要注意的是,就像D.5之后包含B为NULL的那样,我把它的子分支称为D.5 xc),其B列为132158。
答案 0 :(得分:3)
第1步:拆分排序标准
使用SQL Server字符串操作和强制转换方法将以下字段添加到结果集中:
Major (varchar) Minor (int) Remainder yourOtherFields
-------------------------------------------------------------
A 1 NULL ...
A 1 xc ...
...
(例如,可以通过获取第一个.
和下一个.
或)
之间的子字符串并将其转换为整数来提取Minor。)
第2步:排序
SELECT myField1, myField2, ...
FROM (...SQL from Step 1...) AS mySource
ORDER BY Major, Minor, Remainder
这确保了Major和Remainder上的字符串排序顺序,但是Minor上的整数排序顺序。
答案 1 :(得分:1)
试试这个。 它使用PARSENAME函数是sql实际上是将一个对象名称拆分成它的各个部分,但是会用点分割任何东西......
SELECT A, B
FROM (
SELECT A, B,
CASE
WHEN LEN(A) - LEN(REPLACE(A, '.', '')) = 3 THEN A
WHEN PATINDEX('%.', REPLACE(A, ')', '.')) > 0 THEN REPLACE(A, ')', '.') + 'x'
ELSE REPLACE(A, ')', '.')
END as dummy
FROM ABCD) data
ORDER BY LEFT(data.A, 1),
CONVERT(INT, CASE
WHEN ISNUMERIC(PARSENAME(data.dummy, 4)) = 1 THEN PARSENAME(data.dummy, 4)
WHEN ISNUMERIC(PARSENAME(data.dummy, 3)) = 1 THEN PARSENAME(data.dummy, 3)
WHEN ISNUMERIC(PARSENAME(data.dummy, 2)) = 1 THEN PARSENAME(data.dummy, 2)
WHEN ISNUMERIC(PARSENAME(data.dummy, 1)) = 1 THEN PARSENAME(data.dummy, 1)
END), data.A
此查询可能无法满足您数据中的所有排列,但这是一个开始。 你明白了。
答案 2 :(得分:0)
试试这个好友。不是很优雅,但它应该做的伎俩:
SELECT
*
FROM ABCD
ORDER BY
LEFT(A,CHARINDEX('.',A,1)-1),
CAST(
LEFT(
RIGHT(A,LEN(A)-CHARINDEX('.',A,1)),
ISNULL(
NULLIF(CHARINDEX('.',RIGHT(A,LEN(A)-CHARINDEX('.',A,1)),1),0),
CHARINDEX(')',RIGHT(A,LEN(A)-CHARINDEX('.',A,1)),1)
)
-1
)
AS INT)