用于数据透视的SQL
我在SQL Server中创建了一个视图;它基本上就是一个工资单表,同一月的同一名员工会有多条记录。
我想把整份数据合并成单行,即每位员工一行。每位员工可能有,也可能没有加班(OT)。
| 员工编号 | 工资单号 | 工资单日期 | 小时数 | 基本工资 | 住房津贴 | 班次 | 子女 | 加班1 | 加班2 | 加班3 | 总工资 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 123456 | 3456 | 31/03/2021 | 0 | NULL | 123 | 456 | 321 | NULL | NULL | NULL | 900 |
| 123456 | 3456 | 31/03/2021 | 162.23 | 1234 | NULL | NULL | NULL | NULL | NULL | NULL | 1234 |
| 123456 | 3456 | 31/03/2021 | 12.25 | NULL | NULL | NULL | NULL | NULL | 240 | NULL | 240 |
| 123456 | 3456 | 31/03/2021 | 10 | NULL | NULL | NULL | NULL | 120 | NULL | NULL | 120 |
期望的输出如下:
| 员工编号 | 工资单号 | 工资单日期 | 基本工资 | 基本工资时数 | 住房津贴 | 班次 | 子女 | 加班1 | 加班1时数 | 加班2 | 加班2时数 | 加班3 | 加班3时数 | 总工资 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 123456 | 3456 | 31/03/2021 | 1234 | 162.23 | 123 | 456 | 321 | 120 | 10 | 240 | 12.25 | 0 | 0 | 2494 |
如何在SQL Server中实现?
解决方案
正如其他人已经提到的,你是在寻找常规聚合和条件聚合的组合。条件聚合在聚合函数内部使用CASE表达式。
-- Sample data - which will come from the view in your case
with cte as (
select *
from (
values
(123456, 3456, '31/03/2021', 0, null, 123, 456, 321, cast(null as int), cast(null as int), cast(null as int), 900)
, (123456, 3456, '31/03/2021', 162.23, 1234, null, null, null, null, null, null, 1234)
, (123456, 3456, '31/03/2021', 12.25, null, null, null, null, null, 240, null, 240)
, (123456, 3456, '31/03/2021', 10, null, null, null, null, 120, null, null, 120)
) x (Employee_ID, PSNO, PSDATE, HOURS, BASIC, HRA, SHIFT, CHILD, OT1, OT2, OT3, GROSS)
)
-- The query which returns your desired results
select Employee_ID, PSNO, PSDATE
, isnull(max(BASIC), 0) BASIC
, max(case when BASIC is not null then HOURS end 0 end) BASIC_HRS
, max(HRA) HRA
, max(SHIFT) SHIFT
, max(CHILD) CHILD
, isnull(max(OT1), 0) OT1
, max(case when OT1 is not null then HOURS else 0 end) OT1_HRS
, isnull(max(OT2), 0) OT2
, max(case when OT2 is not null then HOURS else 0 end) OT2_HRS
, isnull(max(OT3), 0) OT3
, max(case when OT3 is not null then HOURS else 0 end) OT3_HRS
, sum(GROSS) GROSS
from cte
group by Employee_ID, PSNO, PSDATE;
备注:这种条件聚合的形式只有在你确定被聚合的多行中,某一列只有一个正的有效值用于条件聚合时才会起作用。max 函数随后会正确地选择这个唯一的正值。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。