Sql server的行转列
业务场景:有如下一张表,希望汇总成下面的查询结果。
原始数据表 EmployeeTable:一个员工身兼多个岗位。
Employee Role Level
张三 工程师 3
张三 经理 5
李四 工程师 2
李四 主管 4
王五 操作工 8
希望查询结果:
Employee 工程师 经理 主管 操作工
张三 3 5
李四 2 4
王五 8
其实这个需求就是一个行转列的过程。
1.传统的方法:case when
SELECT Employee,
MAX(CASE ROLW WHEN '工程师' THEN LEVEL ELSE '' END) AS 工程师,
MAX(CASE ROLW WHEN '经理' THEN LEVEL ELSE '' END) AS 经理,
MAX(CASE ROLW WHEN '主管' THEN LEVEL ELSE '' END) AS 主管,
MAX(CASE ROLW WHEN '操作工' THEN LEVEL ELSE '' END) AS 操作工
FROM EmployeeTable GROUP BY Employee
缺点是:每添加一个岗位,这个查询就需要更新
2.方法二:PIVOT搭配聚合函数:
使用透视表,重新聚合实现行转列
SELECT *
FROM (
SELECT
Employee,
Role,
Level
FROM EmployeeTable
) AS SourceTable
PIVOT (
MAX(Level) -- 使用聚合函数(如 MAX/AVG)处理同一员工的重复岗位,作为值显示
FOR Role IN (
[工程师], [经理], [主管],[操作工] -- 列出所有岗位名称, 指名道姓让这一列做新列
)
) AS PivotTable;
缺点是:和方法一样,每添加一个岗位,这个查询就需要更新
3.方法三:PIVOT搭配聚合函数+动态
先拼接成sql查询语句,然后再用sp_executesql执行获得结果。
DECLARE @columns NVARCHAR(MAX), @sql NVARCHAR(MAX);
-- 动态获取所有岗位名称
SELECT @columns = (
SELECT DISTINCT QUOTENAME(Role) + ',' -- 处理特殊字符(如空格)
FROM EmployeeTable
FOR XML PATH('')
);
SET @columns = LEFT(@columns, LEN(@columns) - 1); -- 移除末尾逗号
-- 生成动态 PIVOT 查询
SET @sql = N'
SELECT Employee, ' + @columns + '
FROM (
SELECT Employee, Role, Level
FROM EmployeeTable
) AS SourceTable
PIVOT (
MAX(Level)
FOR Role IN (' + @columns + ')
) AS PivotTable;';
-- 执行动态 SQL
EXEC sp_executesql @sql;
实现动态查询。