SQL Server discarding SPACE during GROUP BY
SQL Server discarding SPACE during GROUP BY
问题
Looks like SQL Server (tried on 2008 R2) is doing an RTRIM
on columns in GROUP BY
clause. Did anyone notice this? Am I missing something here?
The two selects are returning the same result set in the query below, which should not be the case I believe.
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)
Please let me know your thoughts...
回答1
It's actually doing the opposite, but the observable effects are the same.
When comparing two strings of unequal length, one of the rules of SQL (the standard, not just SQL Server) is that the shorter string is padded with spaces until it's the same length, and then the comparison is performed.
If you want to avoid being surprised, you'll need to add a non-space character at the end of each string.
In fact, checking the standard text, it appears that there are two options:
4.6 Type conversions and mixing of data types
...
When values of unequal length are compared, if the collating sequence for the comparison has the
NO PAD
attribute and the shorter value is equal to a prefix of the longer value, then the shorter value is considered less than the longer value. If the collating sequence for the comparison has thePAD SPACE
attribute, for the purposes of the comparison, the shorter value is effectively extended to the length of the longer by concatenation of <space>s on the right.
But all of the SQL Server collations I'm aware of are PAD SPACE
.
回答2
This is easier to see:
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
Notice the space between A and dot. It chose the 1-space version over the 0-space.
Notice also that the D group chooses the one with 2 trailing spaces over the 4.
So, no it's not performing an RTRIM. It's somewhat of a soft bug however, because it's arbitrarily choosing one of the two columns (the one it came across first) as the result of the GROUP BY which could possibly throw you off if spaces mattered.
直接来测试
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;
SELECT Name, REPLACE(Name, ' ', '-') FROM @t
也可以用datalenth来确定长度,
Note: The DATALENGTH() function counts both leading and trailing spaces when calculating the length of the expression.
SELECT Name, REPLACE(Name, ' ', '-'),DATALENGTH(Name) FROM @t
WHERE [Name] IN ('A','D')
作者:Chuck Lu GitHub |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2021-01-21 What is the difference between --save and --save-dev?
2021-01-21 Webpack - A Detailed Introduction
2021-01-21 Webpack Tutorial: Understanding How it Works
2021-01-21 How to use Babel without Webpack
2021-01-21 babel-loader
2021-01-21 Babel is a JavaScript compiler.
2021-01-21 Compiling vs Transpiling