Chr*_*n C 10 sql t-sql sql-server
我没有找到任何解释以下行为的文档,db和服务器级别排序规则都是CI(Case Insensitive),为什么它在这方面仍然区分大小写?
--Works
SELECT CASE name WHEN 'a' THEN 'adam' ELSE 'bertrand' END AS name, COUNT(value) FROM
(
SELECT 'a' AS name,1 AS value
UNION
SELECT 'b',1
UNION
SELECT 'b',2
)a
GROUP BY CASE name WHEN 'a' THEN 'adam' ELSE 'bertrand' END
--Returns an Error Message, please note the "B" in Bertrand in the GROUP BY
SELECT CASE name WHEN 'a' THEN 'adam' ELSE 'bertrand' END name, COUNT(value) FROM
(
SELECT 'a' AS name,1 AS value
UNION
SELECT 'b',1
UNION
SELECT 'b',2
)a
GROUP BY CASE name WHEN 'a' THEN 'adam' ELSE 'Bertrand' END
Run Code Online (Sandbox Code Playgroud)
第二个查询返回此错误消息.
Msg 8120,Level 16,State 1,Line 2
列'a.name'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中.
小智 5
这更多是扩展评论,真正的答案.
我相信这个问题来自SQL Server如何尝试评估case语句表达式.
要证明服务器是大小写的,您可以运行以下两个语句
SELECT CASE WHEN 'Bertrand' = 'bertrand' THEN 'true' ELSE 'false' end
Run Code Online (Sandbox Code Playgroud)
-
DECLARE @base TABLE
(NAME VARCHAR(1)
,value INT
)
INSERT INTO @base Values('a',0),('b',0),('B',0)
SELECT * FROM @base
SELECT name, COUNT(value) AS Cnt
FROM @base
GROUP BY NAME
Run Code Online (Sandbox Code Playgroud)
结果:

正如你在这里看到的那样,即使第二行中的字母是小写,第三行中的字母是大写,group by子句也会忽略这种情况.查看执行计划有两个表达式
Expr 1007 COUNT([value])
Expr 1004 CONVERT_IMPLICIT(int,[Expr1007],0)
Run Code Online (Sandbox Code Playgroud)
现在当我们改变它 case
SELECT CASE WHEN name = 'a' THEN 'adam' ELSE 'bertrand' END AS name, COUNT(value) AS Cnt
FROM @base
GROUP BY CASE WHEN name = 'a' THEN 'adam' ELSE 'bertrand' END
Run Code Online (Sandbox Code Playgroud)
执行计划显示3个表达式.2从上面和新的
Expr 1004 CASE WHEN [NAME]='a' THEN 'adam' ELSE 'bertrand' END
Run Code Online (Sandbox Code Playgroud)
所以此时聚合函数不再评估列的值,name而是现在它评估表达式的值.
我认为发生的事情可能是不正确的.当SQL Server将CASEstatement in SELECT和GROUP BYclause转换为表达式时,它会提供不同的表达式值.在这种情况下,您也可以使用'bertrand'in select和'charlie'
in group by子句,因为如果CASE表达式不是select和group by子句之间的100%匹配,SQL Server会将它们视为Expr不再匹配的不同aka(列).
更新:
为了更进一步,以下声明也将失败.
SELECT CASE WHEN name = 'a' THEN 'adam' ELSE UPPER('bertrand') END AS name
,COUNT(value) AS Cnt
FROM @base
GROUP BY CASE WHEN name = 'a' THEN 'adam' ELSE UPPER('Bertrand') END
Run Code Online (Sandbox Code Playgroud)
即使在UPPER()函数中包装不同的case字符串,SQL Server仍然无法处理它.