PAYATHON 2026

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,还需要明确如何合并多张工资单,以及如何在结果中展示这些字段。

备注:内容仅供参考。