首页 > 解决方案 > Sum 函数在分组后不显示单行中的总值

问题描述

我必须展示在不同日期工作的每个员工的总工作时间。

我可以使用 group by 和 sum 函数,但我有多个列要展示,它给出了多行的相同结果总和。此外,我不想在 group by 子句中写下每个列名,因为它不适合查询编写方式。

我设法使用联接从不同的表中获取员工的工作时间,但无法将它们总结为单行记录。但是它在多行中显示总和。

我用来获取所有数据的脚本如下:

Select e.employeecode, Isnull(e.PreferredName,e.FirstNames) + '
    ' + e.LastName as [Name], w.Position
    , sum(h.TotalHours) over (partition by e.employeecode order by e.employeecode)[TotalHours]
    , e.Salary, e.startdate    
From employee e
Left join Appointment ap on ap.EmployeeCode = e.EmployeeCode
left join Work w on w.WorkCode = ap.workCode 
left join HistoricalAllowance h on h.EmployeeCode = e.EmployeeCode 
left join TransPerPaySequence TP on tp.PaySequence = h.PaySequence
Where tp.PeriodEnd between '2021-04-24' and '2021-05-07'
and h.AllowanceCode in ('99','1000') and
and ap.isactive ='1'
group by e.EmployeeCode

写完脚本后现在看起来:

员工代码 姓名 位置 全部小时数 薪水 开始日期
1234 安娜 员工通讯 63.45 500 40792
1234 安娜 员工通讯 486.45 500 40792
2345 杰基 经理 126.9 700 41395
2345 杰基 经理 961.05 700 41395
2345 杰基 经理 67.05 700 41395
3456 马哈托 人力资源 402.3 570 41933
3456 马哈托 人力资源 67.05 570 41933
3456 马哈托 人力资源 126.9 570 41933
3456 马哈托 人力资源 126.9 570 41933

我想要的方式

员工代码 姓名 位置 全部小时数 薪水 开始日期
1234 安娜 员工通讯 549.9 500 40792
2345 杰基 经理 1155 700 41395
3456 马哈托 人力资源 723.15 570 41933

请帮助,让我知道我错过了什么。

提前致谢

标签: sqlsql-servertsql

解决方案


我很感激不想列出GROUP BY. . . 但出于稍微不同的原因:如果您可以避免聚合,那么查询可能会更快。

SQL Server 提供了一个方便的解决方案,使用OUTER APPLY

select e.employeecode,
       coalesce(e.PreferredName, e.FirstNames) + ' ' + e.LastName as Name,
       w.Position,
       h.TotalHoursTotalHours, e.Salary, e.startdate    
From employee e Left join
     Appointment ap
     on ap.EmployeeCode = e.EmployeeCode left join
     Work w
     on w.WorkCode = ap.workCode outer apply
     (select sum(h.TotalHours) as TotalHours
      from HistoricalAllowance h join 
           TransPerPaySequence TP
           on tp.PaySequence = h.PaySequence
      where h.EmployeeCode = e.EmployeeCode and
            tp.PeriodEnd between '2021-04-24' and '2021-05-07' and
            h.AllowanceCode in ('99','1000') 
     ) h
where ap.isactive = '1';

推荐阅读