SQL Server Varchar列中数值的奇怪排序行为

时间:2019-02-05 09:17:36

标签: sql sql-server tsql

有人可以解释一下这种奇怪的行为吗?

select a from (
    select '1' as a
    union all
    select '2' as a
    union all
    select '-3' as a
) as b
order by a desc

select a from (
    select '4' as a
    union all
    select '5' as a
    union all
    select '-3' as a
) as b
order by a desc

查询1的结果

-3
2
1

查询2的结果

5
4
-3

好像-字符被忽略了。不过,我还是说SQL Server根据ASCII代码订购varchars。

所以预期结果将是:

2
1
-3   //ascii - is before 0-9

和:

 5
 4
-3  //ascii - is before 0-9

如果我在数字前添加字母,我会得到相同的结果:

select a from (
    select 'a1' as a
    union all
    select 'a2' as a
    union all
    select '-a3' as a
) as b
order by a desc

select a from (
    select 'a4' as a
    union all
    select 'a5' as a
    union all
    select '-a3' as a
) as b
order by a desc

3 个答案:

答案 0 :(得分:4)

SQL Server中的实际排序顺序完全取决于活动的collation(默认的排序顺序或显式指定的排序规则)。

例如您使用二进制排序规则,就可以得到这种情况的期望值:

select a from (
    select '1' as a
    union all
    select '2' as a
    union all
    select '-3' as a
) as b
order by a COLLATE Latin1_General_BIN desc
/* Result: 2, 1, -3  */

select a from (
    select '4' as a
    union all
    select '5' as a
    union all
    select '-3' as a
) as b
order by a COLLATE Latin1_General_BIN desc
/* Result: 5, 4, -3  */

要查看所有归类,请运行以下命令:

select * from sys.fn_helpcollations()

答案 1 :(得分:1)

您应像这样将归类设置为Latin1_General_BIN:

select a from (
select '1' as a
union all
select '0' as a
union all
select '-1' as a
) as b
order by a COLLATE Latin1_General_BIN desc

答案 2 :(得分:1)

如果您使用数字而不是字符串...

select a from (
    select 1 as a
    union all
    select 2 as a
    union all
    select -3 as a
) as b
order by a desc

...然后数字按预期排序:

2
1
-3