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

求助:SQL Server多列逆透视(Unpivot)问题处理

解决SQL Server中带缺失列的逆透视问题

嘿,我来帮你搞定这个逆透视的需求!首先我得先模拟一个符合你描述的表结构(毕竟你没给具体列名,我就按常见的多列场景来假设)——比如原表有ID作为主键,然后是Article1/Article2/Article3、Amount1/Amount2/Amount3,但没有Price1,只有Price2/Price3。

先看示例原表

首先创建测试表和插入数据:

CREATE TABLE YourTable (
    ID INT PRIMARY KEY,
    Article1 VARCHAR(50),
    Article2 VARCHAR(50),
    Article3 VARCHAR(50),
    Amount1 INT,
    Amount2 INT,
    Amount3 INT,
    -- 注意:没有Price1,只有Price2、Price3
    Price2 DECIMAL(10,2),
    Price3 DECIMAL(10,2)
);

INSERT INTO YourTable VALUES
(1, 'Apple', 'Banana', 'Cherry', 10, 20, 30, 1.50, 2.00),
(2, 'Orange', 'Grape', NULL, 15, 25, NULL, 0.80, 1.20);

推荐方案:用CROSS APPLY实现灵活逆透视

因为存在缺失的Price1列,用CROSS APPLY + VALUES的方法会比原生UNPIVOT更直观,也更容易处理缺失值的情况。直接把每一行拆成对应序号的多行,缺失的Price1就用NULL填充:

SELECT 
    t.ID,
    ca.ItemNumber,
    ca.Article,
    ca.Amount,
    ca.Price
FROM YourTable t
CROSS APPLY (
    VALUES
        (1, t.Article1, t.Amount1, NULL), -- Price1不存在,用NULL填充
        (2, t.Article2, t.Amount2, t.Price2),
        (3, t.Article3, t.Amount3, t.Price3)
) ca (ItemNumber, Article, Amount, Price)
WHERE 
    -- 可选:过滤掉所有字段都为空的无效行
    ca.Article IS NOT NULL OR ca.Amount IS NOT NULL OR ca.Price IS NOT NULL;

结果说明

执行后会得到这样的结果:

IDItemNumberArticleAmountPrice
11Apple10NULL
12Banana201.50
13Cherry302.00
21Orange15NULL
22Grape250.80

完全符合逆透视的需求,而且完美处理了Price1缺失的情况。

备选方案:用UNPIVOT实现(稍繁琐)

如果一定要用原生UNPIVOT,得先手动补上Price1列(值为NULL),然后多次逆透视再关联,步骤会多一些:

SELECT 
    ID,
    ItemNumber,
    Article,
    Amount,
    Price
FROM (
    SELECT 
        ID,
        Article1,
        Article2,
        Article3,
        Amount1,
        Amount2,
        Amount3,
        CAST(NULL AS DECIMAL(10,2)) AS Price1, -- 手动添加Price1列
        Price2,
        Price3
    FROM YourTable
) src
UNPIVOT (
    Article FOR ItemNumber IN (Article1, Article2, Article3)
) upvt_article
UNPIVOT (
    Amount FOR ItemNumber_Amount IN (Amount1, Amount2, Amount3)
) upvt_amount
UNPIVOT (
    Price FOR ItemNumber_Price IN (Price1, Price2, Price3)
) upvt_price
WHERE 
    upvt_article.ItemNumber = upvt_amount.ItemNumber_Amount
    AND upvt_article.ItemNumber = upvt_price.ItemNumber_Price;

这个方法也能得到同样的结果,但需要确保三次逆透视的序号匹配,不如CROSS APPLY简洁,所以更推荐第一种方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 20:43:18