【问题标题】:How do I restrict my SQL aggregation Rollups to a specific grouping?如何将我的 SQL 聚合汇总限制为特定的分组?
【发布时间】:2021-06-01 14:30:27
【问题描述】:

以下 SQL 返回 5 个分组列和两个聚合列:

select ten.TenancyName,
       svd.EmployeeId,
       usr.DisplayName,
       tjt.JobTitle,
       tjc.Name as JobCategory,
       count(svd.ratingpoints) as NumReviews, 
       avg(svd.ratingpoints) as Rating 
  from surveydetails svd
  join AbpUsers usr on usr.Id = svd.EmployeeId
  join AbpTenants ten on ten.Id = usr.TenantId
  join TenantJobTitle tjt on tjt.TenantId = usr.TenantId and tjt.Id = usr.JobTitleId
  join TenantJobTitleCategories tjc on tjc.Id = tjt.JobTitleCategory
 where svd.employeeid is not null
   and svd.CreationTime > '2020-01-01'
   and svd.CreationTime < '2021-12-31'
 group by ten.TenancyName,
          rollup(svd.EmployeeId,
                 usr.DisplayName,
                 tjt.JobTitle,
                 tjc.Name)
order by ten.TenancyName,
         svd.EmployeeId,
         usr.DisplayName,
         tjt.JobTitle,
         tjc.[Name]

我确实希望汇总到 TenancyName 级别,但它不需要所有其他中间汇总行。实际上,您可以看到从 Doctor's (Employee's) 行向上滚动到 EmployeeId 会在每一行上产生完全相同的值,因为这些是一对一的数据属性。唯一有意义的级别是 TenancyName 级别,因为每个租户中有多个医生。

事实上,我可以使用 HAVING 子句或将其作为外部选择的子选择来消除不需要的行,从而过滤掉不需要的行。例如:

   select ten.TenancyName,
      svd.EmployeeId,
      usr.DisplayName,
      tjt.JobTitle,
      tjc.Name as JobCategory,
      count(svd.ratingpoints) as NumReviews, 
      avg(svd.ratingpoints) as Rating 
 from surveydetails svd
 join AbpUsers usr on usr.Id = svd.EmployeeId
 join AbpTenants ten on ten.Id = usr.TenantId
 join TenantJobTitle tjt on tjt.TenantId = usr.TenantId and tjt.Id = usr.JobTitleId
 join TenantJobTitleCategories tjc on tjc.Id = tjt.JobTitleCategory
where svd.employeeid is not null
  and svd.CreationTime > '2020-01-01'
  and svd.CreationTime < '2021-12-31'
group by ten.TenancyName,
         rollup(svd.EmployeeId,
                usr.DisplayName,
                tjt.JobTitle,
                tjc.Name)
having (svd.EmployeeId is null and 
        usr.DisplayName is null and 
        tjt.JobTitle is null and 
        tjc.Name is null)
       or
       (ten.TenancyName is not null and 
        svd.EmployeeId is not null and 
        usr.DisplayName is not null and 
        tjt.JobTitle is not null and 
        tjc.Name is not null)
order by ten.TenancyName,
         svd.EmployeeId,
         usr.DisplayName,
         tjt.JobTitle,
         tjc.[Name]

这提供了我想要的,但如果这可以通过 group by / rollup 构造自然地完成,我应该认为从简单性和性能的角度来看这将是更可取的。

【问题讨论】:

  • 用您正在使用的数据库标记您的问题。
  • 我投票决定重新打开,因为被提名为重复的文章只对知道存在分组集合之类的东西的人有用。我没有,我只是从@GordonLinoff 对这个问题的回答中发现了关于分组集的信息。既然我知道了关于分组集的知识,那么其他文章作为辅助信息肯定是有用的。但这两个问题来自两个不同的参考框架,并不是重复的。

标签: sql sql-server group-by rollup


【解决方案1】:

大多数支持rollup 的数据库也支持grouping sets。我更喜欢grouping sets,因为它可以让您明确控制组。

例如,如果您想按所有列、租户分组并有一个总行,您可以使用:

group by grouping sets ( (ten.TenancyName, svd.EmployeeId, usr.DisplayName, tjt.JobTitle, tjc.Name),
                         (ten.TenancyName),
                         ()
                       )

【讨论】:

猜你喜欢
  • 2015-09-28
  • 2020-03-07
  • 2014-03-21
  • 1970-01-01
  • 1970-01-01
  • 2013-12-05
  • 1970-01-01
  • 2019-10-10
  • 2017-01-24
相关资源
最近更新 更多