SQL Server首先按字母排序,然后按数字排序

时间:2020-09-29 08:54:51

标签: sql sql-server

在过去的2/3个小时中,我一直在尝试按照自己的方式对varchar进行排序,但是我无法弄清楚。基本上,这是最接近我想要的查询:

select Plantmaat
from Plant
Group by Plantmaat
order by (CASE WHEN Plantmaat like '[a-z]%' THEN 0 ELSE 1 END), Plantmaat ASC;

输出以下内容:

LEV
PLG
S 10-12
S 12-14
S 14-16
S 16-18
UITS
10
-10
11
12
14
15
-9

但这是我要实现的目标:

LEV
PLG
UITS
S 10-12
S 12-14
S 14-16
S 16-18
-9
-10
10
11
12
14
15

您在这里看到的最大问题是,它不会对仅包含字母的行进行排序,并且负数最终位于底部。

3 个答案:

答案 0 :(得分:1)

这似乎符合您的逻辑:

select *
from tab
order by
  case when col not like '%[0-9-]%' then 0 else 1 end -- no digits
 ,case when col like '[^0-9-]%' then 0 else 1 end     -- starting with non-digit
 ,case when col like '-%' then 0 else 1 end           -- negative values first
 ,len(col)                                            -- shorter (=smaller) values first
 ,col
 

请参见fiddle

答案 1 :(得分:0)

我能建议的最好的方法如下,但是,不会给您想要的结果:

ORDER BY CASE WHEN TRY_CONVERT(int,YourVarchar) IS NULL THEN 0 ELSE 1 END,
         CASE WHEN TRY_CONVERT(int,YourVarchar) IS NULL THEN YourVarchar ELSE NULL END
         TRY_CONVERT(int,YourVarchar);

正如我提到的,由于 derpirscher highlighted的原因,这不会为您的问题提供结果。对于字符串,'U'的值比'S''P'高,因此将在它们的两者之后而不是在'P'之后且之前'S'

对于数字,数字-9-10大,因此也将在其后而不是之前进行排序。

但是,正如我提到的,这里的 real 解决方案是修复您的设计。如果要在同一列中同时混合数字数据和字符串数据,并且希望数字数据的行为类似于数字值,则需要两列;一个用于字符串数据,一个用于数字数据。

但是,如果您不希望数值数据表现为数值(因此'2''10'“大”,而'4' + '7''47' ),那么varchar很好,但是除非更改设计,否则您不能指望它像数字值一样发挥作用。

答案 2 :(得分:0)

如果您希望数字按数字的顺序排列,则您希望-10在-9之前。如果这是您真正想要的,则可以使用:

select *
from tab
order by try_convert(int, col), col;

如果您确实真的想先-9,可以进行以下调整:

select *
from tab
order by sign(try_convert(int, col)),
         abs(try_convert(int, col)), col;
相关问题