在过去的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
您在这里看到的最大问题是,它不会对仅包含字母的行进行排序,并且负数最终位于底部。
答案 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;