【发布时间】:2017-01-30 22:24:52
【问题描述】:
在配置为不区分大小写的 SQL Server 上,当 [n][var]char 列不是第一个 group by 列时,group by 可能会产生有趣的结果。本质上,它看起来就像遇到“第一”的任何行(在没有订单的情况下“第一”是未定义的):该分组获胜。例如:
select x.[day], x.[name], count(1) as [count]
from (
select 1 as [day], 'a' as [name]
union all select 1, 'A'
union all select 2, 'A'
union all select 2, 'a'
) x group by x.[day], x.[name]
返回,对我来说:
day name count
----------- ---- -----------
1 A 2
2 a 2
使用min(x.[name]) 无效,因为分组已经发生。
我不能在group by 之前添加order by 之前,因为那是非法的;并添加order by 之后 group by 只是定义分组后的输出顺序 - 它仍然给出a 和A。
那么:有没有一种理智的方式来做到这一点,其中所有分组的大小写至少是一致的? (我将在另一天留下单独运行的一致性问题)
所需的输出,或者:
day name count
----------- ---- -----------
1 A 2
2 A 2
或:
day name count
----------- ---- -----------
1 a 2
2 a 2
编辑:不在组间一致时破坏大写。所以没有上/下。因此,如果其中一个组的值始终为BcDeF,我希望该行的结果为BcDeF,而不是bcdef 或BCDEF。
【问题讨论】:
-
您希望
(1, 'A'), (2, 'a')的输出是什么?为(1, 'A'), (2, 'a'), (3, 'A')?为(1, 'A'), (1, 'a'), (2, 'A'), (2, 'a')? -
@AndriyM 很好的问题;也许这在数据库层无法解决;我天真地想“第二列中的所有'a'或所有'A'”,但是......
-
为了完整起见,我最终通过标准化返回的结果在调用站点“修复”了这个问题。窗口函数方法可能最接近我的需要,但在我的场景中(运行时生成的任意复杂度的报告查询)实施起来并不实际。
-
@MarcGravell 如果数据在 Andriy 的第一个示例中具有不同标题的组,那么在任何层都不可能。并非没有“破坏”某些群体的资本化。如果你想在数据库中这样做,Lamak 的答案是有效的。
-
@ypercubeᵀᴹ 这取决于;这在调用层工作得很好——关于选择哪个版本有点随意,但至少每次运行都是一致的,这对我的目的来说已经足够了:gist.github.com/mgravell/c4385cef8121e6aa10e6cb9773ff838c
标签: sql sql-server group-by case-sensitive case-insensitive