如何在SQL中对含字符串列的表执行Pivot(行转列)操作
如何在SQL中将ID/Label/Text结构的表行转列(Pivot操作)
没问题,我来帮你搞定这个行转列的需求!先明确下你的输入和目标结构:
输入表结构及数据
ID Label Text 10 Lead Source Internet 10 Display Washington 10 Sale Brick 10 Colour Blue
目标表结构及数据
id Lead Source Display Sale Colour 10 Internet Washington Brick Blue
下面分两种场景给出解决方案:
1. 通用方案(适配所有SQL数据库)
如果你的数据库不支持PIVOT关键字(比如MySQL 5.x及更早版本),可以用CASE WHEN结合聚合函数的方式实现,这是行转列的底层逻辑,所有SQL方言都支持:
SELECT ID, MAX(CASE WHEN Label = 'Lead Source' THEN Text END) AS `Lead Source`, MAX(CASE WHEN Label = 'Display' THEN Text END) AS `Display`, MAX(CASE WHEN Label = 'Sale' THEN Text END) AS `Sale`, MAX(CASE WHEN Label = 'Colour' THEN Text END) AS `Colour` FROM YourTableName -- 替换成你的实际表名 GROUP BY ID;
解释:
- 按
ID分组,把同一ID下的多行数据合并成一行 CASE WHEN会针对每个Label提取对应的Text值,不匹配的Label会返回NULL- 用
MAX()(或MIN()/SUM(),只要是聚合函数即可)过滤掉NULL,留下每个Label对应的唯一值 - 注意列名含空格时,不同数据库的标识符引用方式不同:MySQL用反引号``,SQL Server用
[],Oracle用""
2. 简化方案(支持PIVOT关键字的数据库)
如果你的数据库支持PIVOT语法(比如SQL Server、Oracle、PostgreSQL 11+、MySQL 8.0+),可以用更简洁的写法:
SQL Server/Oracle写法
SELECT ID, [Lead Source], [Display], [Sale], [Colour] FROM YourTableName PIVOT ( MAX(Text) -- 因为每个Label对应唯一值,用MAX/MIN都可以 FOR Label IN ([Lead Source], [Display], [Sale], [Colour]) ) AS PivotResult;
MySQL 8.0+写法
SELECT ID, `Lead Source`, `Display`, `Sale`, `Colour` FROM YourTableName PIVOT ( MAX(Text) FOR Label IN (`Lead Source`, `Display`, `Sale`, `Colour`) ) AS PivotResult;
解释:
PIVOT是专门的行转列语法糖,本质和CASE WHEN方案逻辑一致- 括号里先指定聚合函数(这里用
MAX()),然后用FOR Label IN()列出要转成列的所有Label值 - 同样要注意列名的空格处理,用对应数据库的标识符引用方式
补充说明
如果你的Label值是动态变化的(无法提前知道所有可能的Label),那需要用动态SQL自动生成列名。比如在SQL Server中可以通过拼接字符串生成CASE WHEN或PIVOT语句,这属于进阶需求,如果是固定的Label值,上面的静态写法就足够啦。
内容的提问来源于stack exchange,提问作者Cameron
相关产品推荐
相关产品推荐

