如何实现SQL Server SELECT查询结果的行列转换
实现行转列:将3列多行数据转换为多列两行结构
要实现这种行转列的结构,核心是把原表中Column01的每个值转为新表的列,同时将Column02和Column03分别作为新表的两行数据。以下以SQL Server为例给出实现方案:
动态SQL实现(适配26行数据)
由于目标列数对应26个Item,手动写列名效率极低,用动态SQL自动生成列名是最优解:
- 先生成目标列名列表:
DECLARE @cols NVARCHAR(MAX); SELECT @cols = STRING_AGG(QUOTENAME(Column01), ', ') FROM Table01 WHERE <conditions>; -- 替换为你的过滤条件
- 构建并执行动态PIVOT语句:
DECLARE @sql NVARCHAR(MAX); SET @sql = N' SELECT ' + @cols + N' FROM ( -- 将Column02和Column03拆分为两行数据,标记类型 SELECT Column01, CAST(Column02 AS VARCHAR(MAX)) AS Value, -- 转换为字符串统一类型 ''Column02'' AS [Type] FROM Table01 WHERE <conditions> UNION ALL SELECT Column01, Column03 AS Value, ''Column03'' AS [Type] FROM Table01 WHERE <conditions> ) AS src PIVOT ( MAX(Value) -- 聚合函数不影响结果,每个Item对应唯一值 FOR Column01 IN (' + @cols + N') ) AS pvt '; EXEC sp_executesql @sql;
代码说明
- 先用
UNION ALL把Column02和Column03的数据拆分为两行,每行带上类型标记; - 通过
PIVOT将Column01的Item值转为列名,聚合函数MAX(Value)用于适配PIVOT的语法要求(每个列对应唯一值,MAX不会改变结果); - 把
Column02转为VARCHAR(MAX)是为了和Column03类型统一,避免UNION ALL时的类型冲突。
如果使用MySQL等其他数据库,核心逻辑类似,只是生成列名的函数(比如用GROUP_CONCAT)和动态SQL的执行方式有所不同。
内容的提问来源于stack exchange,提问作者Yousef Ayash
相关产品推荐
相关产品推荐

