求助: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;
结果说明
执行后会得到这样的结果:
| ID | ItemNumber | Article | Amount | Price |
|---|---|---|---|---|
| 1 | 1 | Apple | 10 | NULL |
| 1 | 2 | Banana | 20 | 1.50 |
| 1 | 3 | Cherry | 30 | 2.00 |
| 2 | 1 | Orange | 15 | NULL |
| 2 | 2 | Grape | 25 | 0.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
相关产品推荐
相关产品推荐

