如何将我的 SQL 聚合 Rollup 限制为特定分组?
How do I restrict my SQL aggregation Rollups to a specific grouping?
以下 SQL returns 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(Employee)的行向上滚动到 EmployeeId 在每一行上产生完全相同的值,因为这些是一对一的数据属性。唯一有意义的级别是 TenancyName 级别,因为每个租户中有多个医生。
事后,我可以使用 HAVING 子句或将其作为外部 select 的子 select 来消除不需要的行,后者将过滤掉不需要的行。例如:
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 结构自然地完成,我认为从简单性和性能的角度来看,这将是更可取的。
大多数支持 rollup
的数据库也支持 grouping sets
。我更喜欢 grouping sets
因为它可以让您明确控制组。
例如,如果您想按所有列、租期进行分组,并有一个总行,您可以使用:
group by grouping sets ( (ten.TenancyName, svd.EmployeeId, usr.DisplayName, tjt.JobTitle, tjc.Name),
(ten.TenancyName),
()
)
以下 SQL returns 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(Employee)的行向上滚动到 EmployeeId 在每一行上产生完全相同的值,因为这些是一对一的数据属性。唯一有意义的级别是 TenancyName 级别,因为每个租户中有多个医生。
事后,我可以使用 HAVING 子句或将其作为外部 select 的子 select 来消除不需要的行,后者将过滤掉不需要的行。例如:
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 结构自然地完成,我认为从简单性和性能的角度来看,这将是更可取的。
大多数支持 rollup
的数据库也支持 grouping sets
。我更喜欢 grouping sets
因为它可以让您明确控制组。
例如,如果您想按所有列、租期进行分组,并有一个总行,您可以使用:
group by grouping sets ( (ten.TenancyName, svd.EmployeeId, usr.DisplayName, tjt.JobTitle, tjc.Name),
(ten.TenancyName),
()
)