如何用SQL将同一员工的多行项目数据拆分为固定多列
实现Projects表的行转列(固定5列)
需求是将每个员工参与的项目按顺序拆分到固定的5列(Col1至Col5)中,项目数不足5的列填充NULL。以下是两种可行的SQL实现方案:
方案一:窗口函数+条件聚合(兼容多数数据库)
先通过ROW_NUMBER()给每个员工的项目按顺序生成序号,再用条件聚合将行转成固定列:
SELECT ID, MAX(CASE WHEN proj_seq = 1 THEN Project END) AS Col1, MAX(CASE WHEN proj_seq = 2 THEN Project END) AS Col2, MAX(CASE WHEN proj_seq = 3 THEN Project END) AS Col3, MAX(CASE WHEN proj_seq = 4 THEN Project END) AS Col4, MAX(CASE WHEN proj_seq = 5 THEN Project END) AS Col5 FROM ( -- 子查询:给每个ID下的项目生成顺序序号 SELECT ID, Project, ROW_NUMBER() OVER(PARTITION BY ID ORDER BY Project) AS proj_seq FROM projects ) t GROUP BY ID ORDER BY ID;
说明:
PARTITION BY ID确保序号按员工分组生成,ORDER BY Project保证项目排序一致(可根据实际需求调整排序字段)- 外层通过
CASE判断序号提取对应项目,MAX()用于聚合分组后的结果(每个ID+序号仅一条数据,不影响最终值)
方案二:窗口函数+PIVOT(适用于SQL Server、Oracle等支持PIVOT的数据库)
如果你的数据库支持原生PIVOT语法,可使用更简洁的写法:
SELECT ID, [1] AS Col1, [2] AS Col2, [3] AS Col3, [4] AS Col4, [5] AS Col5 FROM ( SELECT ID, Project, ROW_NUMBER() OVER(PARTITION BY ID ORDER BY Project) AS proj_seq FROM projects ) t PIVOT ( MAX(Project) FOR proj_seq IN ([1], [2], [3], [4], [5]) ) p ORDER BY ID;
说明:
- 子查询同样生成项目序号,
PIVOT将序号值(1-5)转成列名,通过MAX(Project)获取对应项目值 - 最后将默认列名
[1]等重命名为Col1至Col5
两种方案都能输出你期望的结果,可根据使用的数据库类型选择合适的写法。
内容的提问来源于stack exchange,提问作者NewbieSQL_Germany
相关产品推荐
相关产品推荐

