简体   繁体   English

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

[英]Strange sort behaviour for numeric values in Varchar column in SQL Server

Can someone please explain this strange behaviour: 有人可以解释一下这种奇怪的行为:

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

Result for query 1: 查询结果1:

-3
2
1

Result for query 2: 查询2的结果:

5
4
-3

It looks like - character is ignored. 看起来-字符被忽略。 I though, that SQL Server orders varchars based on ASCII code. 我虽然说,SQL Server根据ASCII代码订购varchars。

So expected result would be: 因此,预期结果将是:

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

and: 和:

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

I get same result if I add a letter before number: 如果在数字前添加字母,则会得到相同的结果:

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

Actual sort order in SQL Server depends totally on the active collation (either the default one, or a collation that is specified explicitly). SQL Server中的实际排序顺序完全取决于活动排序规则 (默认排序规则或显式指定的排序规则)。

If eg you use a binary collation, you'll get what you were expecting for this case: 例如,如果您使用二进制排序规则,则可以得到这种情况的期望值:

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  */

To see all collations, run this: 要查看所有归类,请运行以下命令:

select * from sys.fn_helpcollations()

You should set the collation to Latin1_General_BIN like this : 您应该将排序规则设置为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

If you use numbers instead of strings ... 如果您使用数字而不是字符串...

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

... then the numbers are sorted as expected: ...然后数字按预期排序:

2
1
-3

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM