我还没有找到任何文档来解释以下行为,数据库和服务器级排序都是CI(不区分大小写),为什么在这方面它仍然区分大小写?
--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
第二个查询会传回这个错误消息。
消息8120,级别16,状态1,第2行
数据行'a.name'在选取清单中无效,因为它未包含在汇总函数或GROUP BY子句中。
5条答案
按热度按时间mftmpeh81#
这更多的是引申的议论,真实的回答。
我认为此问题是由于SQL Server试图计算
case
语句表达式的方式造成的。要证明服务器不区分大小写,可以运行以下两个语句
实验结果:
正如您在这里所看到的,尽管第二行中的字母是小写,第三行中的字母是大写,但group by子句忽略大小写。
现在当我们将其更改为
case
时执行计划显示3个表达式。2个来自上面,另一个是新的
因此此时聚合函数不再计算列
name
的值,而是计算表达式的值。我认为发生的是可能不正确。当SQL Server将
SELECT
和GROUP BY
子句中的CASE
语句都转换为表达式时,它会得到不同的表达式值。在这种情况下,您最好在select
中执行'bertrand'
,在group by
子句中执行'charlie'
,因为如果CASE
表达式不是100% select和group by子句之间的匹配SQL Server会将它们视为不再匹配的不同的Expr
aka(列)。更新:
若要进一步执行此步骤,下列陈述式也会失败。
即使在
UPPER()
函数中 Package 了不同的大小写字符串,SQL Server仍然无法处理它。neskvpey2#
问题在于select和group by中的语句应该相同,但您可以按如下所示编写查询
这不是区分大小写的问题,请看这个示例
而“亚当”和“伯特兰”的情况是一样的。
z4bn682m3#
你发现了一些真正奇怪的东西,但我认为问题在于你在groupby语句中使用了case语句。它应该是:
分组依据应该应用于整个表而不是单个行。我可能缺少这样做的一些原因,但我认为按值进行有条件分组是没有意义的。
我更惊讶的是,第一个查询能用,而不是第二个查询不能用。比较'a' = 'A'与比较一列和另一列有细微的不同。SQL Server在检查列是否在group by中时似乎不使用排序规则设置。您从第二个查询收到的错误消息是:'select中的此列与group by中的列不相同'而不是'这些值不相等'。
sxpgvts34#
这不是一个答案,而是一个评论,它需要比评论部分提供的更多的空间和功能。
如果根本问题是要最大限度地降低在查询中犯此类错误的风险,因为必须在GROUP BY和SELECT中维护复杂的表达式,那么您可以首先使用CROSS APPLY来避免重复。
你可以做的
现在您需要在一个地方维护复杂的分组表达式。
希望您使用的是SQL Server 2005或更高版本,以便能够使用此方法。否则,您始终可以使用派生表:
这种方式的最后查询不太优雅,但可以获得相同的结果:表达式只定义一次。
pxyaymoc5#
定义不起作用
在你的第二个我得到一个语法错误
消息8120,级别16,状态1,第1行列'a.name'在选择列表中无效,因为它既未包含在聚合函数中,也未包含在GROUP BY子句中。
此时,它甚至还没有尝试处理查询
为什么你坚持语法错误是因为CI不被尊重
这是语法错误-不是执行错误
select必须与组匹配
因此,出于某种原因,SQL解析器需要匹配大小写
重要的是它如何处理查询
如果您有区分大小写的表,您是否希望TSQL要求区分大小写的列名和表名?
这对我的工作
adam的和为6它同时支持小写(a)和大写(A)
这说明此group by IS不区分大小写
并且不区分大小写