You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将SQL表中部分列执行类转置转换并保留其余列作为行

解决SQL宽表转窄表(列转行)的方案

嘿,你这个需求其实是典型的**列转行(逆透视/Unpivot)**操作,完全不用折腾复杂的JOIN,不同数据库有不同的简洁实现方式,我给你整理几种常用的方案:

1. 通用方案(适配几乎所有SQL数据库)

如果你的数据库没有原生的逆透视语法(比如MySQL、SQLite),用UNION ALL拼接每个年份的行就可以实现,这是最通用的写法:

SELECT col1, col2, col3, '2000' AS year, `2000` AS amount FROM your_table
UNION ALL
SELECT col1, col2, col3, '2001' AS year, `2001` AS amount FROM your_table
UNION ALL
SELECT col1, col2, col3, '2002' AS year, `2002` AS amount FROM your_table
UNION ALL
SELECT col1, col2, col3, '2003' AS year, `2003` AS amount FROM your_table
ORDER BY col1, col2, col3, year;

注意:因为你的年份列名是数字,所以需要用反引号()包裹(MySQL/SQLite),如果是SQL Server则用方括号([])。最后加ORDER BY`是为了让结果和你给出的示例顺序完全一致。

2. SQL Server/Azure SQL 原生Unpivot方案

如果用的是支持UNPIVOT语法的数据库,直接用原生语法会更简洁:

SELECT col1, col2, col3, year, amount
FROM your_table
UNPIVOT (
    amount FOR year IN ([2000], [2001], [2002], [2003])
) AS unpvt
ORDER BY col1, col2, col3, year;

这里UNPIVOT会自动把指定的列(2000-2003)转换成year和amount两列的多行数据。

3. PostgreSQL 专属方案

PostgreSQL可以用LATERAL JOIN结合VALUES子句来实现,写法清晰直观:

SELECT t.col1, t.col2, t.col3, x.year, x.amount
FROM your_table t
LATERAL (
    VALUES
        ('2000', t."2000"),
        ('2001', t."2001"),
        ('2002', t."2002"),
        ('2003', t."2003")
) AS x(year, amount)
ORDER BY col1, col2, col3, year;

简单解释下为什么之前的JOIN思路不对:JOIN是用来关联不同表的行数据,而你需要的是把同一行内的多列拆分成多行,这正是逆透视操作的核心场景,所以换个思路用上面的方法就能轻松搞定啦~

内容的提问来源于stack exchange,提问作者JRJR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 16:18:14