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

SQL中Pivot实现需求:根据给定源表生成指定结构输出结果

实现SQL数据转换:从宽表到目标结构

我来帮你搞定这个数据转换的需求!这个场景其实是**先列转行(Unpivot)再行转列(Pivot)**的组合操作,咱们一步步拆解实现:

核心思路

  1. 列转行(Unpivot):把原始表中Jan、Feb这类月份列,转换成Month(月份名称)和Value(对应数值)的行数据,让每个月份的数值都变成单独的一行。
  2. 行转列(Pivot):把第一步得到的Tag列(Secondary、Primary)转换成独立的列,让每个Brand+Year+Month组合下,能同时显示两个Tag的数值。

方案1:SQL Server原生PIVOT/UNPIVOT写法

如果你的数据库是SQL Server(支持原生PIVOT语法),可以用下面的语句:

SELECT 
    Brand,
    Year,
    Month,
    Secondary,
    Primary
FROM (
    -- 第一步:Unpivot,把月份列转成行
    SELECT 
        Brand,
        Year,
        Tag,
        Month,
        Value
    FROM YourOriginalTable  -- 替换成你的实际表名
    UNPIVOT (
        Value FOR Month IN (Jan, Feb)
    ) AS Unpvt
) AS PivotSource
-- 第二步:Pivot,把Tag转成列
PIVOT (
    MAX(Value) FOR Tag IN (Secondary, Primary)
) AS Pvt
ORDER BY Brand, Year DESC, Month;

说明

  • 这里用MAX(Value)是因为每个Brand+Year+Month+Tag组合只有唯一值,用MAX/MIN/AVG都能得到正确结果,选哪个都可以。
  • 最终结果会自动把没有对应Tag的数值显示为NULL,完美匹配你要的输出。

方案2:通用CASE WHEN写法(兼容所有数据库)

如果你的数据库不支持原生PIVOT(比如MySQL、SQLite等),这个兼容性拉满的写法更合适:

SELECT
    Brand,
    Year,
    Month,
    MAX(CASE WHEN Tag = 'Secondary' THEN Value END) AS Secondary,
    MAX(CASE WHEN Tag = 'Primary' THEN Value END) AS Primary
FROM (
    -- 第一步:用UNION ALL模拟Unpivot,把每个月份拆成行
    SELECT Brand, Year, Tag, 'Jan' AS Month, Jan AS Value FROM YourOriginalTable
    UNION ALL
    SELECT Brand, Year, Tag, 'Feb' AS Month, Feb AS Value FROM YourOriginalTable
) AS UnpvtData
GROUP BY Brand, Year, Month
ORDER BY Brand, Year DESC, Month;

说明

  • 用UNION ALL把Jan和Feb列分别拆成独立的行,实现列转行的效果。
  • 分组后通过CASE WHEN提取对应Tag的数值,没有匹配到的Tag会返回NULL,完全符合期望的结果结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:38:38