问题描述
排序顺序有问题,结果是在字母前列出 0 和 00 REVISION 值。我希望先对字母进行排序,然后再对数字进行排序。这意味着 0 和 00 应该在字母之后。除了 0,00 之外的所有其他排序都是正确的。
SELECT D.PRIO,D.REVISION,ROW_NUMBER() OVER(ORDER BY PRIO,REVISION ) RN FROM (
SELECT disTINCT CONVERT(INT,LEFT(REVISION,PATINDEX('%[^0-9]%',REVISION+'z')-1)) 'PRIO',REVISION FROM DOCUMENTS )D
ORDER BY D.PRIO,D.REVISION ;
PRIO | 修订 | RN |
---|---|---|
0 | 0 | 1 |
0 | 00 | 2 |
0 | A | 3 |
0 | a | 4 |
0 | B | 5 |
0 | b | 6 |
0 | C | 7 |
0 | c | 8 |
0 | D | 9 |
0 | d | 10 |
0 | E | 11 |
0 | e | 12 |
0 | F | 13 |
0 | f | 14 |
0 | G | 15 |
0 | g | 16 |
0 | H | 17 |
0 | h | 18 |
0 | 我 | 19 |
0 | i | 20 |
0 | J | 21 |
0 | K | 22 |
0 | L | 23 |
0 | M | 24 |
0 | P | 25 |
0 | R | 26 |
0 | S | 27 |
0 | SU | 28 |
0 | X | 29 |
0 | XX | 30 |
0 | Y | 31 |
1 | 01 | 32 |
1 | 1 | 33 |
1 | 1A | 34 |
2 | 02 | 35 |
2 | 2 | 36 |
2 | 2. | 37 |
3 | 03 | 38 |
3 | 3 | 39 |
4 | 04 | 40 |
4 | 4 | 41 |
5 | 05 | 42 |
5 | 5 | 43 |
6 | 06 | 44 |
6 | 6 | 45 |
7 | 07 | 46 |
7 | 7 | 47 |
8 | 08 | 48 |
8 | 8 | 49 |
9 | 09 | 50 |
9 | 9 | 51 |
10 | 10 | 52 |
11 | 11 | 53 |
12 | 12 | 54 |
13 | 13 | 55 |
解决方法
一种方法是将 TRY_CONVERT
与 CASE
表达式一起使用:
ORDER BY CASE WHEN TRY_CONVERT(int,REVISION) IS NULL THEN 0 ELSE 1 END,REVISION
这将首先对无法转换的值进行排序,这将是您的 alpha(数字)值,然后是可以转换的值。然后,在这些组中,它会按字母顺序排列它们,这意味着 'AB'
在 'CD'
之前,'12'
在 '2'
之前。
如果您希望数值按数字排序,我个人建议您修复您的设计,并将数值与 alpha 值分开存储。如果您“不能”,那么您将需要单独的子句:
ORDER BY CASE WHEN TRY_CONVERT(int,CASE WHEN TRY_CONVERT(int,REVISION) IS NULL THEN REVISION END,TRY_CONVERT(int,REVISION)
,
我的建议是对 rn
的计算进行逻辑更改。然后使用 rn
进行排序:
SELECT D.PRIO,D.REVISION,ROW_NUMBER() OVER (ORDER BY PRIO,(CASE WHEN REVISION IN ('0','00') THEN 1 ELSE 2 END) DESC,REVISION ) AS RN
FROM (SELECT DISTINCT CONVERT(INT,LEFT(REVISION,PATINDEX('%[^0-9]%',REVISION+'z')-1)) as PRIO,REVISION
FROM DOCUMENTS
) D
ORDER BY RN