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

SQL Server如何实现多列同时PIVOT透视查询

问题描述

我对PIVOT操作掌握不熟练(此处无双关语意),目前仅完成了一半需求实现,第二部分功能开发遇到阻碍。

测试基础信息

  • 当前数据展示效果:
    当前数据效果截图
  • 临时表结构及测试数据:
CREATE TABLE #temptable ([PriceName] VARCHAR(50), [PriceName_Change] VARCHAR(50), [PriceVal] DECIMAL(28, 2), [PriceVal_Change] DECIMAL(28, 2), [Portfolio] NVARCHAR(200), [benchmark] NVARCHAR(200) , [EffectiveDate] DATE);
INSERT INTO #temptable ([PriceName], [PriceName_Change], [PriceVal], [PriceVal_Change], [Portfolio], [benchmark], [EffectiveDate])
VALUES 
 ('OilPrice', 'OilPrice_CHANGE', 1607.00, 3.61, N'PORT45', N'SP500',N'2022-06-02T00:00:00')
,('OilPrice', 'OilPrice_CHANGE', 1607.00, 3.61, N'PORT45', N'SP500',N'2022-06-01T00:00:00')
,('OilPrice', 'OilPrice_CHANGE', 607.00, 12.61, N'PORT45', N'SP500',N'2022-05-31T00:00:00')

需求详情

业务规则:OilPrice关联取PriceVal列数值,PriceName_Change关联取PriceVal_Change列数值,需要对这两组映射字段同时执行PIVOT透视。
目前仅实现单列PIVOT查询,无法完成双列同时透视效果,已编写的单PIVOT代码如下:

SELECT
    portfolio
  , EffectiveDate
  , [OilPrice]
FROM
    (
        SELECT
             SM.portfolio
           , SM.PriceVal
           , SM.PriceName
           , SM.EffectiveDate
        FROM #temptable SM
    ) AS tbl
PIVOT
(
    SUM(PriceVal)
    FOR PriceName IN ([OilPrice])
) AS pvt;

期望输出结果格式:

OilPrice | OilPrice_Change | Portfolio | Benchmark | EffectiveDate |
1607.00  | 3.61            | PORT45    | SP500     | 2022-06-02    |
1607.00  | 3.61            | PORT45    | SP500     | 2022-06-01    |
607.00   | 12.61           | PORT45    | SP500     | 2022-05-31    |
实现方法

提供两种可直接运行的实现方案:

方案1:条件聚合(适配当前固定列场景,性能最优)

当前透视列固定为OilPrice,不需要嵌套PIVOT语法,直接按维度分组做条件聚合即可拿到结果,写法简洁执行效率高:

SELECT
    SUM(CASE WHEN PriceName = 'OilPrice' THEN PriceVal END) AS OilPrice,
    SUM(CASE WHEN PriceName_Change = 'OilPrice_CHANGE' THEN PriceVal_Change END) AS OilPrice_Change,
    Portfolio,
    benchmark AS Benchmark,
    EffectiveDate
FROM #temptable
GROUP BY Portfolio, benchmark, EffectiveDate

方案2:双PIVOT关联(适配后续多列扩展场景)

如果后续需要新增更多价格类透视字段,可以分别对值列做PIVOT后再按公共维度关联,扩展性更强:

SELECT
    pvt_val.OilPrice,
    pvt_change.OilPrice_CHANGE AS OilPrice_Change,
    pvt_val.Portfolio,
    pvt_val.benchmark AS Benchmark,
    pvt_val.EffectiveDate
FROM
(
    -- 透视PriceVal列
    SELECT Portfolio, benchmark, EffectiveDate, [OilPrice]
    FROM (SELECT Portfolio, benchmark, EffectiveDate, PriceName, PriceVal FROM #temptable) t
    PIVOT (SUM(PriceVal) FOR PriceName IN ([OilPrice])) p_val
) pvt_val
INNER JOIN
(
    -- 透视PriceVal_Change列
    SELECT Portfolio, benchmark, EffectiveDate, [OilPrice_CHANGE]
    FROM (SELECT Portfolio, benchmark, EffectiveDate, PriceName_Change, PriceVal_Change FROM #temptable) t
    PIVOT (SUM(PriceVal_Change) FOR PriceName_Change IN ([OilPrice_CHANGE])) p_change
) pvt_change
ON pvt_val.Portfolio = pvt_change.Portfolio 
AND pvt_val.benchmark = pvt_change.benchmark 
AND pvt_val.EffectiveDate = pvt_change.EffectiveDate

两种方案执行结果完全匹配预期格式,当前场景优先选择方案1即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 04:48:16