【问题标题】:Group By With Rollup and Count(Distinct)使用汇总和计数分组(不同)
【发布时间】:2014-11-25 11:35:57
【问题描述】:

我在使用Group By With Rollup 时遇到了一个小问题,同时获得了CountDistinct

问题在于 Rollup 汇总只是所有分组中 Distinct 值的总数,而不是所有分组的汇总。

这里有一个测试场景来说明我的意思:

Create Table #Test
(
    GroupId Int Not Null,
    Value   Int Not Null
)

Insert  #Test (GroupId, Value)
Values  (1, 1),(1, 2),(1, 3),(1, 4),(1, 5),(1, 5),(1, 1),
        (2, 1),(2, 6),(2, 7),(2, 5),(2, 7),(2, 5),
        (3, 9),(3, 10),(3, 11),(3, 4),(3, 5),(3, 7),(3, 8),(3, 5),(3, 7),(3, 8)

对于这个特定的表,如果我运行这个查询:

Select  Case When Grouping(GroupId) = 1 Then 'Total:' Else Str(GroupId) End As GroupId, 
        Count(Distinct Value) Count
From    #Test
Group By GroupId With Rollup
Order By Grouping(GroupId), GroupId

我得到以下结果:

GroupId Count
-------------
1       5
2       4
3       7
Total:  11  

我对 Total 行的预期结果是 16,但我只得到 11 - 这是所有组中 Distinct 值的总数。

从查询中删除 Distinct 确实会显示该 Rollup 的预期结果:

Select  Case When Grouping(GroupId) = 1 Then 'Total:' Else Str(GroupId) End As GroupId, 
        Count(Value) Count
From    #Test
Group By GroupId With Rollup
Order By Grouping(GroupId), GroupId

产生这些结果:

GroupId Count
-------------
1       7
2       6
3       10
Total:  23

它按预期总结了组。

我的问题是:RollupCount Distinct 上是正常的吗?是否有其他类似Rollup 的选项可用于Grouping 以显示16 而不是上面示例中的11?

【问题讨论】:

  • 您想要 DISTINCT 结果在 SELECT 中,但所有值都在最后一个汇总行中?
  • 我想要每个组的不同计数,以及所有组的摘要。这些组正确显示了计数,但我希望汇总行显示所有组的总数(例如,显示 16,而不是 11)。

标签: sql sql-server group-by distinct rollup


【解决方案1】:

你可以通过嵌套查询和使用技巧得到你想要的:

select GroupId, Sum(Count) as Count
from (Select (Case When Grouping(GroupId) = 1 Then 'Total:' Else Str(GroupId) End) As GroupId, 
             Count(Distinct Value) as Count
      From  #Test
      Group By GroupId
     ) t
Group By GroupId With Rollup
Order By Grouping(GroupId), GroupId;

第二个group by 在逻辑上不进行聚合,因为每个组只有一行。它只是为了在rollup 中获得您想要的值。

【讨论】:

  • 啊 - 我希望在没有嵌套的情况下实现这一目标。知道为什么Rollup 会这样吗?
  • @Siyual 。 . .汇总在count(distinct)。许多人会认为这种行为是一件好事。不同计数的总和与事物并集的不同计数不同。
  • 啊,有道理。因此,Rollup 本质上将相同的聚合应用于所有组作为一个整体,而不是将相同的聚合应用于每个组的结果。这是有道理的,为什么Count(Distinct) 会这样。感谢您的帮助!
  • @Siyual 。 . .想想min()max()avg() 应该发生什么,这会很有意义。
【解决方案2】:

创建测试数据:

DECLARE @Test TABLE
(
    GroupId Int Not Null,
    Value   Int Not Null
)

Insert  @Test 
(GroupId, Value)
Values  (1, 1),(1, 2),(1, 3),(1, 4),(1, 5),(1, 5),(1, 1),
        (2, 1),(2, 6),(2, 7),(2, 5),(2, 7),(2, 5),
        (3, 9),(3, 10),(3, 11),(3, 4),(3, 5),(3, 7),(3, 8),(3, 5),(3, 7),(3, 8)

我将第三列更改为按组 ID 和值区分的分组

Select  Case When Grouping(GroupId) = 1 Then 'Total:' Else Str(GroupId) End As GroupId, 
       Count(DISTINCT Value) As Count,
        Count(Value) AS Count2,
        Count(DISTINCT (GroupId * 10) + Value) AS Count3
From    @Test
Group By GroupId With Rollup
Order By Grouping(GroupId), GroupId

这是输出:

GroupId Count Count2 Count3
1       5     7      5
2       4     6      4
3       7     10     7
Total:  11    23     16

【讨论】:

    猜你喜欢
    • 2022-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多