2012-10-11 30 views
6

看起来像SQL服务器(试过2008 R2)是列做一个RTRIMGROUP BY条款。有没有人注意到这个?我在这里错过了什么吗?SQL Server组中丢弃空间。通过

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

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) 

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

回答

7

它实际上是反其道而行之,但可观察到的效果是相同的。

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

如果你想避免被惊讶,你需要在每个字符串的结尾处添加一个非空字符。


事实上,检查standard text,似乎有两种选择:

4.6类型转换和数据类型

的混合...

当值比较不等长度 ,如果比较的整理顺序具有 ,NO PAD属性和较短的值lue等于 的前缀值越长,则越短的值被认为小于 的较长值。如果用于比较的比较排序序列具有 ,PAD SPACE属性,则为了比较的目的,通过在右侧连接<个空间>将较短值有效地扩展到较长的长度 。

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

+1

不是。因此,标准声称它填充到最大长度*用于比较*,但问题是关于GROUP BY的输出,它是** NOT **如您所期望的那样较长的一个,如果确实中间体被延长(他们不是)。简单地说,'a'='a'(尾随空格被忽略) – RichardTheKiwi

+3

@RichardTheKiwi - 第8.2节“根据整理顺序,即使两个字符串的长度不同,也可以将两个字符串相等,即使它们长度不同也可能不相同 当操作 MAX,MIN,DISTINCT,对分组列的引用以及UNION,EXCEPT和INTERSECT运算符引用字符 字符串时,**这些操作从 a选择的具体值这样的相等值的集合取决于实现。**“(强调增加) –

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组选择所述一个与2个尾部空格在4

所以,没有它不执行RTRIM。但它有点错误,因为它是任意作为GROUP BY的结果选择两个列之一(它遇到的第一个),如果空间重要可能会抛出你。