SQL Server行转列查询实现求助:将指定行数据转为列结构
解决SQL Server行转列(PIVOT)问题
固定列名的PIVOT实现
假设你的原始表结构如下(对应源数据图):
| EmpID | AttrName | AttrValue |
|---|---|---|
| 1 | Name | 张三 |
| 1 | Age | 30 |
| 1 | Department | 技术部 |
| 2 | Name | 李四 |
| 2 | Age | 28 |
| 2 | Department | 市场部 |
要转换为目标结构(对应结果图):
| EmpID | Name | Age | Department |
|---|---|---|---|
| 1 | 张三 | 30 | 技术部 |
| 2 | 李四 | 28 | 市场部 |
可以用以下PIVOT查询:
SELECT EmpID, [Name], [Age], [Department] FROM ( SELECT EmpID, AttrName, AttrValue FROM EmployeeAttributes -- 替换成你的实际表名 ) AS SourceTable PIVOT ( MAX(AttrValue) -- 每个EmpID+AttrName唯一时,MAX/MIN/ANY都可使用 FOR AttrName IN ([Name], [Age], [Department]) -- 明确列出要转成列的属性名 ) AS PivotTable;
关键注意点
- 子查询仅保留必要列:分组列(如
EmpID)、行转列标识列(如AttrName)、值列(如AttrValue),多余列会导致PIVOT自动额外分组,出现重复行。 - 聚合函数适配场景:若每个
EmpID+AttrName仅对应一条数据,MAX/MIN都能得到正确结果;若存在多条数据,需根据需求选择聚合逻辑(如合并、取最新值)。 - 列名需用方括号包裹:如果属性名含空格或特殊字符,必须用
[]或QUOTENAME()处理,避免语法错误。
动态列的PIVOT实现(属性名不固定时)
如果属性名是动态变化的,无法提前写死列名,可使用动态SQL生成PIVOT语句:
DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX); -- 获取所有唯一属性名,拼接成列名列表 SELECT @cols = STRING_AGG(QUOTENAME(AttrName), ', ') FROM (SELECT DISTINCT AttrName FROM EmployeeAttributes) AS t; -- 构建动态PIVOT查询 SET @query = ' SELECT EmpID, ' + @cols + ' FROM ( SELECT EmpID, AttrName, AttrValue FROM EmployeeAttributes ) AS SourceTable PIVOT ( MAX(AttrValue) FOR AttrName IN (' + @cols + ') ) AS PivotTable;'; -- 执行动态SQL EXEC sp_executesql @query;
内容的提问来源于stack exchange,提问作者DasDepp
相关产品推荐
相关产品推荐

