代码之家  ›  专栏  ›  技术社区  ›  Ryan

SQL Server中奇怪的比较结果

  •  2
  • Ryan  · 技术社区  · 7 年前

    对于没有依赖于排序规则的显式顺序的字符(即,没有大小写折叠和/或没有去除重音的字符),顺序基于基本字符集中代码点的序号值。如果一个字符串是另一个字符串的前缀,则较短的字符串首先进行排序。

    那么为什么会发生以下情况?

    Demo: How '2017/8/22 1:33:53' precedes '2017-08-13 23:12:33.411'

    我预计“2017/8/22 1:33:53”在“2017-08-13 23:12:33.411”之后,因为 / 紧随其后 - . 这是不是因为特殊排序在Chinese\u PRC\u CI\u中作为排序?如果是这样,我在哪里可以找到规格?

    3 回复  |  直到 7 年前
        1
  •  3
  •   sepupic    7 年前

    我预计“2017/8/22 1:33:53”将在“2017-08-13 23:12:33.411”之后出现 因为/在-。这是因为

    是的,是因为 Chinese_PRC_CI_AS 排序规则

    如果是这样,我在哪里可以找到规格?

    规则很复杂,但你可以在这里找到它们: UNICODE COLLATION ALGORITHM

    enter image description here

    在您的情况下,您可以尝试使用 binary Chinese_PRC_BIN2 ,在这种特殊情况下,它会给你理想的结果,但它对于字母排序是不可接受的,我的意思是在欧洲语言中,二进制排序总是将大写字母放在所有小写字母之前,但我不知道中文符号应该如何排序

    declare @t table (s nvarchar(100))
    insert into @t values (N'2017/8/22 1:33:53'),  (N'2017-08-13 23:12:33.411')
    
    select *
    from @t
    order by s collate Chinese_PRC_BIN2;
    

    Bin2排序也适用于“非unicode大小写”,如图中所示:

    select case 
          when '2017/8/22 1:33:53' collate Chinese_PRC_BIN2 < 
               '2017-08-13 23:12:33.411' collate Chinese_PRC_BIN2 
          then 'TRUE' 
          else 'FALSE' 
       end;
    

    enter image description here

        2
  •  1
  •   Vladimir Baranov    7 年前

    它不仅仅是关于ASCII码。

    / - 是0x2D,但字符串比较规则取决于排序规则,并且这些规则可能非常复杂,不仅要考虑字符代码的值。

    - 在某些排序规则中,符号以特殊的方式处理。

    DECLARE @T1 TABLE (Value varchar(100) COLLATE Chinese_PRC_CI_AS);
    DECLARE @T2 TABLE (Value varchar(100) COLLATE Latin1_General_CI_AS);
    DECLARE @T3 TABLE (Value varchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS);
    
    INSERT INTO @T1 VALUES
    ('abc'),
    ('abc-def'),
    ('abcdef'),
    ('abc-');
    
    INSERT INTO @T2 VALUES
    ('abc'),
    ('abc-def'),
    ('abcdef'),
    ('abc-');
    
    INSERT INTO @T3 VALUES
    ('abc'),
    ('abc-def'),
    ('abcdef'),
    ('abc-');
    
    SELECT * FROM @T1 ORDER BY Value;
    SELECT * FROM @T2 ORDER BY Value;
    SELECT * FROM @T3 ORDER BY Value;
    

    后果

    T1(Chinese\u PRC\u CI\u AS)

    +---------+
    |  Value  |
    +---------+
    | abc     |
    | abc-    |
    | abcdef  |
    | abc-def |
    +---------+
    

    T2(拉丁文1\u General\u CI\u AS)

    +---------+
    |价值|
    +---------+
    |abc公司|
    |abc-|
    |abc def|
    

    T3(SQL\u Latin1\u General\u CP1\u CI\u AS)

    +---------+
    |  Value  |
    +---------+
    | abc     |
    | abc-    |
    | abc-def |
    | abcdef  |
    +---------+
    

    注意,第三个表中的SQL排序规则产生的结果顺序不同。


    还要注意,如果将列类型更改为 nvarchar ,在这个特定示例中,效果消失。换句话说,处理 -

        3
  •  0
  •   cco    7 年前

    对于没有依赖于排序规则的显式顺序的字符(即,没有大小写折叠和/或没有去除重音的字符),顺序基于基本字符集中代码点的序号值。如果一个字符串是另一个字符串的前缀,则较短的字符串首先进行排序。
    / 紧随其后 - .