SQL Server 如何将员工工资明细多行汇总为一行?
数据阿明
使用条件聚合即可
BASIC、HRA、OT1 等工资项目已经分别存放在各自的列中。用 GROUP BY 按 [Employee ID]、PSNO 和 PSDATE 分组,汇总工资金额,再通过 CASE 将各行的 HOURS 计入对应工时列,就能得到示例结果,无需使用 PIVOT。
查询示例
将 dbo.YourView 替换为实际视图名称。如果员工编号列的名称不同,也要相应调整。
SELECT
[Employee ID],
PSNO,
PSDATE,
SUM(COALESCE(BASIC, 0)) AS BASIC,
SUM(CASE
WHEN BASIC IS NOT NULL THEN COALESCE(HOURS, 0)
ELSE 0
END) AS BASIC_HRS,
SUM(COALESCE(HRA, 0)) AS HRA,
SUM(COALESCE([SHIFT], 0)) AS [SHIFT],
SUM(COALESCE(CHILD, 0)) AS CHILD,
SUM(COALESCE(OT1, 0)) AS OT1,
SUM(CASE
WHEN OT1 IS NOT NULL THEN COALESCE(HOURS, 0)
ELSE 0
END) AS OT1_HRS,
SUM(COALESCE(OT2, 0)) AS OT2,
SUM(CASE
WHEN OT2 IS NOT NULL THEN COALESCE(HOURS, 0)
ELSE 0
END) AS OT2_HRS,
SUM(COALESCE(OT3, 0)) AS OT3,
SUM(CASE
WHEN OT3 IS NOT NULL THEN COALESCE(HOURS, 0)
ELSE 0
END) AS OT3_HRS,
SUM(COALESCE(GROSS, 0)) AS GROSS
FROM dbo.YourView
GROUP BY
[Employee ID],
PSNO,
PSDATE;
工时如何对应到工资项目
查询根据工资项目是否为 NULL 判断该行工时的归属。例如:
SUM(CASE
WHEN OT1 IS NOT NULL THEN COALESCE(HOURS, 0)
ELSE 0
END) AS OT1_HRS
如果某行的 OT1 有值,查询就把该行的 HOURS 计入 OT1_HRS;否则计入 0。COALESCE 会将缺失值转换为 0,因此员工没有 OT3 记录时,OT3 和 OT3_HRS 都显示为 0。
根据题目数据,基本工资行对应 162.23 小时,OT1 对应 10 小时,OT2 对应 12.25 小时。总金额为各行 GROSS 之和:
900 + 1234 + 240 + 120 = 2494
使用前确认数据规则
这个查询适用于各行金额可以累加,且能通过 BASIC、OT1、OT2、OT3 的非 NULL 值识别工时归属的情况。
- 如果同一行的多个工资项目都有值,查询会将该行 HOURS 分别计入对应工时列。如果这些项目应当分摊工时,需要另外提供分摊规则。
- 当前条件使用
IS NOT NULL,金额为 0 的项目也会计入该行工时。如果视图用 0 表示“没有该项目”,需要根据实际业务调整判断条件。 - GROSS 必须是每行的金额。如果视图在每行重复保存整张工资单总额,直接求和会重复计算。
- HOURS 和金额列应使用数值类型。需要保留小数工时时,HOURS 不能使用整数类型。
当前分组结果中,每名员工的每张工资单在每个日期各占一行。如果需要严格按月汇总,而同一个月可能有不同的 PSNO 或 PSDATE,还需要明确如何合并多张工资单,以及如何在结果中展示这些字段。
备注:内容仅供参考。
