当字符串包含空格时,SQL命令的奇怪行为

Zol*_*tai 5 sql-server string space sql-order-by

SQL示例1:

SELECT TestField 
FROM (VALUES('Ne'), ('NE')) AS TestTable(TestField)
ORDER BY TestField COLLATE Latin1_General_CS_AS
Run Code Online (Sandbox Code Playgroud)

结果1:

Ne  
NE
Run Code Online (Sandbox Code Playgroud)

SQL示例2(NE与a之间有2个空格,而Ne与a之间只有1个空格):

SELECT TestField 
FROM (VALUES('Ne a'), ('NE  a')) AS TestTable(TestField)
ORDER BY TestField COLLATE Latin1_General_CS_AS
Run Code Online (Sandbox Code Playgroud)

结果2:

NE  a  
Ne a
Run Code Online (Sandbox Code Playgroud)

有人可以解释吗?

谢谢

Bog*_*ean 3

第二次查询:

SELECT TestField 
FROM (VALUES
    ('Ne a'), 
    ('NE  a')
--    12345
) AS TestTable(TestField)
ORDER BY TestField COLLATE Latin1_General_CS_AS
Run Code Online (Sandbox Code Playgroud)

对于区分大小写的排序规则,按字母顺序(位置 4:< )生成的差异比按大小写顺序(位置 2: < )a生成的差异更重要。之前就是这样。eENE aNe a

另一个例子:和(位置 2)之间的差异比案例顺序(位置 1: vs )a更重要:eE

SELECT '{' + TestField  + '}'
FROM (VALUES
    ('ea'), 
    ('E ') -- or ('E')
--    12
) AS TestTable(TestField)
ORDER BY TestField COLLATE Latin1_General_CS_AS
/*
TestField
---------
{E }
{ea}
*/
Run Code Online (Sandbox Code Playgroud)

更多详细信息,请访问 Rusanu 的博客

更新#1: 您可以使用SQL_EBCDIC037_CP1_CS_AS排序规则:

SELECT TestField 
FROM (VALUES
    ('Ne a'), 
    ('NE  a')
--    12345
) AS TestTable(TestField)
ORDER BY TestField COLLATE SQL_EBCDIC037_CP1_CS_AS
/*
TestField
---------
Ne a
NE  a
*/
Run Code Online (Sandbox Code Playgroud)

但这种排序可能会产生一些奇怪的结果。

例子:

SELECT  x.ColA AS ColA_Latin1_General_CS_AS
FROM (
    SELECT  'A'
    UNION ALL 
    SELECT  'AB'
    UNION ALL 
    SELECT  'ABC'
    UNION ALL   
    SELECT  'zzzz'
) x(ColA)
ORDER BY x.ColA COLLATE Latin1_General_CS_AS
/*
ColA_Latin1_General_CS_AS
----------------------------
A
AB
ABC
zzzz
*/
Run Code Online (Sandbox Code Playgroud)

SELECT  x.ColA AS ColA_SQL_EBCDIC037_CP1_CS_AS
FROM (
    SELECT  'A'
    UNION ALL 
    SELECT  'AB'
    UNION ALL 
    SELECT  'ABC'
    UNION ALL   
    SELECT  'zzzz'
) x(ColA)
ORDER BY x.ColA COLLATE SQL_EBCDIC037_CP1_CS_AS
/*
ColA_SQL_EBCDIC037_CP1_CS_AS
----------------------------
zzzz
A
AB
ABC
*/
Run Code Online (Sandbox Code Playgroud)

注意:我从未使用过SQL_EBCDIC037_CP1_CS_AS排序规则,也不推荐。

更新 #2:文本值分为两列(或更多列)

-- Scenario #1: before/during insert/update, spaces are trimmed with LTRIM
SELECT TestField1 F1,  TestFiel2 AS F2
FROM (VALUES
    ('JOHN', 'ZOE'),  
    ('JOHN', 'Albano')
) AS TestTable(TestField1, TestFiel2)
ORDER BY TestField1 COLLATE Latin1_General_CS_AS, TestFiel2 COLLATE Latin1_General_CS_AS
/*
F1   F2
---- ------
JOHN Albano
JOHN ZOE
*/
-- Scenario #2: during insert/update spaces are not trimmed (with LTRIM)
SELECT LTRIM(TestField1) COLLATE Latin1_General_CS_AS AS F1,  LTRIM(TestFiel2) COLLATE Latin1_General_CS_AS AS F2
FROM (VALUES
    ('JOHN', ' ZOE'),  -- 1 extra space 
    ('JOHN', 'Albano')
) AS TestTable(TestField1, TestFiel2)
ORDER BY F1, F2 
/*
F1   F2
---- ------
JOHN Albano
JOHN ZOE
*/
Run Code Online (Sandbox Code Playgroud)

注意:我将使用 中描述的解决方案Scenario #1