SQL Server在GROUP BY期间丢弃SPACE

时间:2012-10-11 07:36:37

标签: tsql group-by sql-server-2008-r2

看起来SQL Server(在2008 R2上试过)对RTRIM子句中的列进行了GROUP BY。有没有人注意到这个?我在这里错过了什么吗?

这两个选择在下面的查询中返回相同的结果集,这不应该是我认为的情况。

declare @t table(Name varchar(100), Age int)
insert into @t values ('A', 20)
insert into @t values ('B', 30)
insert into @t values ('C', 40)
insert into @t values ('D', 25)
insert into @t values (' A', 21)
insert into @t values ('A ', 32)
insert into @t values (' A ', 28)

select
    Name,
    count(*) Count
from @t
group by Name

select
    rtrim(Name) RtrimmedName,
    count(*) Count
from @t
group by rtrim(Name)

请让我知道你的想法......

3 个答案:

答案 0 :(得分:8)

它实际上正好相反,但可观察到的效果是相同的。

当比较两个不等长的字符串时,SQL的一个规则(标准,而不仅仅是SQL Server)是用较小的字符串填充空格直到它的长度相同,然后比较是进行。

如果你想避免感到惊讶,你需要在每个字符串的末尾添加一个非空格字符。


事实上,检查standard text,似乎有两个选项:

  

4.6类型转换和数据类型混合

     

...

     

当长度不等的值时            比较,如果比较的整理顺序            NO PAD属性和较短的值等于前缀            值越长,则认为较短的值小于            更长的价值。如果比较的整理顺序有            PAD SPACE属性,为了比较的目的,            较短的值有效地延长到较长的长度            通过串联右边的< space&gt ;.

但我所知道的所有SQL Server排序规则都是PAD SPACE

答案 1 :(得分:2)

这更容易看到:

declare @t table (Name varchar(100), Age int)
  insert @t values('A', 20),('B', 30),('C', 40),('D  ', 25)
                 ,(' A', 21),('A ', 32),(' A ', 28),('D    ',10);

  select Name, Replace(Name,' ','-'),
         count(*) Count
    from @t
group by Name

--
NAME  COLUMN_1  COUNT
A     -A        2
A     A-        2
B     B         1
C     C         1
D     D--       2

注意A和点之间的空格。它选择了0空间的1空间版本 另请注意,D组选择在4上有2个尾随空格的那个。

所以,没有它没有执行RTRIM。然而,它有点像 soft 错误,因为它是 任意 选择两列中的一列(它首先遇到的那一列)作为结果如果空间很重要,GROUP BY可能会让你失望。

答案 2 :(得分:0)

我知道这是一个旧线程,但这可能会对其他人有所帮助。我在分组依据中使用了以下内容,以正确识别尾随空格中的差异:

declare @t table(Name varchar(100), Age int)
insert into @t values ('A', 20)
insert into @t values ('B', 30)
insert into @t values ('C', 40)
insert into @t values ('D', 25)
insert into @t values (' A', 21)
insert into @t values ('A ', 32)
insert into @t values (' A ', 28)

select
    Name,
    count(*) Count
from @t
group by Name, DATALENGTH(Name)

通过在组上添加额外的DATALENGTH,还将识别出商品长度的差异。