简体   繁体   English

如何将我的 SQL 聚合汇总限制为特定分组?

[英]How do I restrict my SQL aggregation Rollups to a specific grouping?

The following SQL returns 5 grouped columns and two aggregated columns:以下 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]

在此处输入图像描述

I do want the rollup to the level of TenancyName, but it don't need all the other intermediate rollup lines.我确实希望汇总到 TenancyName 级别,但它不需要所有其他中间汇总行。 In fact, you can see that rolling up from the Doctor's (Employee's) row up to the EmployeeId produces the exact same value on every row because these are one-to-one data attributes.实际上,您可以看到从 Doctor's (Employee's) 行向上滚动到 EmployeeId 会在每一行上产生完全相同的值,因为这些是一对一的数据属性。 The only level where it makes sense to roll up to is the TenancyName level because there are multiple Doctors within each Tenant.唯一有意义的级别是 TenancyName 级别,因为每个租户中有多个医生。

After the fact, I can eliminate the unwanted rows either using a HAVING clause or by making this a sub-select to an outer select which will filter out the undesired rows.事后,我可以使用 HAVING 子句或通过将其作为外部 select 的子选择来消除不需要的行,这将过滤掉不需要的行。 For example:例如:

   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]

在此处输入图像描述

This delivers what I want, but if this can be done naturally via the group by / rollup construct I should think that would be preferable from both simplicity and performance standpoints.这提供了我想要的,但如果这可以通过 group by / rollup 构造自然地完成,我应该认为从简单性和性能的角度来看这将是更可取的。

Most databases that support rollup also support grouping sets .大多数支持rollup的数据库也支持grouping sets I prefer grouping sets because it gives you explicit control over the groups.我更喜欢grouping sets ,因为它可以让您明确控制组。

For instance, if you wanted to group by all the columns, tenancy, and have a total row, you can use:例如,如果您想按所有列、租户分组并拥有总行,您可以使用:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM