SQL使用聚合函数时避免全字段GROUP BY并保留所有列的实现方法
解决方案
你出现数据拆分的核心原因是GROUP BY中包含了th.created_date字段,两条待聚合记录的创建时间不一致,导致被拆分为独立分组分别求和。你可以根据业务需求选择以下两种方案实现需求:
方案1:仅保留单条聚合结果,同时展示所有非重复附加字段
如果你需要保留的start_date、level_data、project_code_1等字段,在同一个task_name分组下取值完全一致,可以直接用聚合函数包裹这些非分组字段,不需要将它们加入GROUP BY列表:
select ti.task_name, MAX(cast(ti.start_date AS VARCHAR)) as start_date, MAX(ld.level_data) as level_data, MAX(pi.project_code_1) as project_code_1, MAX(pi.project_code_2) as project_code_2, SUM(th.previous_completed) as total from task_history th left join task_information ti on ti.id = th.task_id left join project_information pi on ti.project_id = pi.id left join lookup_data ld on ti.activity = ld.id where cast(th.created_date as date) between '2021-06-28' and '2021-06-29' and ti.employee_id = '092cdd13-5f30-4980-93d0-8246239728fd' group by ti.task_name
该方案返回结果和你第二次查询的结构一致,仅返回一条记录,同时补全了所有你需要展示的附加字段。
方案2:保留所有明细行,每行同步展示总求和结果
如果你需要保留每条记录的创建时间等明细信息,同时每行都展示该task_name对应的总求和值,可以使用窗口函数实现,不需要额外加GROUP BY:
select distinct ti.task_name, cast(ti.start_date AS VARCHAR) as start_date, cast(th.created_date AS VARCHAR) as created_date, ld.level_data, pi.project_code_1, pi.project_code_2, SUM(th.previous_completed) OVER(PARTITION BY ti.task_name) as total from task_history th left join task_information ti on ti.id = th.task_id left join project_information pi on ti.project_id = pi.id left join lookup_data ld on ti.activity = ld.id where cast(th.created_date as date) between '2021-06-28' and '2021-06-29' and ti.employee_id = '092cdd13-5f30-4980-93d0-8246239728fd'
该方案会返回所有匹配的明细行,每行的total字段都是该task_name下所有记录的求和值。
内容的提问来源于stack exchange,提问作者jack
相关产品推荐
相关产品推荐

