SQL动态透视(特殊场景):将多行MENGE/PREIS转为带序号列
数据转换解决方案
要实现将多行的MENGE和PREIS转为同一条记录下的多列,核心是先给每个分组内的行标记序号,再通过条件聚合提取对应行的数据。
步骤1:为分组内的行添加序号
先通过ROW_NUMBER()函数,按RABATTNR分组,按MENGE排序(保证行号对应原数据的顺序),为每行生成唯一序号:
SELECT RABATTNR, MENGE, PREIS, ROW_NUMBER() OVER (PARTITION BY RABATTNR ORDER BY MENGE) AS row_num FROM 你的数据表名
执行后会得到带行号的中间结果:
| RABATTNR | MENGE | PREIS | row_num |
|---|---|---|---|
| 222890 | 0.010 | 5.35 | 1 |
| 222890 | 101.000 | 3.85 | 2 |
| 222890 | 500.000 | 3.65 | 3 |
步骤2:通过条件聚合生成目标表
基于上面的中间结果,使用MAX()结合CASE WHEN按行号提取对应列的值,最后按RABATTNR分组:
SELECT RABATTNR, MAX(CASE WHEN row_num = 1 THEN MENGE END) AS MENGE1, MAX(CASE WHEN row_num = 1 THEN PREIS END) AS PREIS1, MAX(CASE WHEN row_num = 2 THEN MENGE END) AS MENGE2, MAX(CASE WHEN row_num = 2 THEN PREIS END) AS PREIS2, MAX(CASE WHEN row_num = 3 THEN MENGE END) AS MENGE3, MAX(CASE WHEN row_num = 3 THEN PREIS END) AS PREIS3 FROM ( SELECT RABATTNR, MENGE, PREIS, ROW_NUMBER() OVER (PARTITION BY RABATTNR ORDER BY MENGE) AS row_num FROM 你的数据表名 ) temp GROUP BY RABATTNR
执行后就能得到你期望的结果:
| RABATTNR | MENGE1 | PREIS1 | MENGE2 | PREIS2 | MENGE3 | PREIS3 |
|---|---|---|---|---|---|---|
| 222890 | 0.010 | 5.35 | 101.000 | 3.85 | 500.000 | 3.65 |
为什么之前的Pivot操作不符合需求?
你之前直接用MENGE作为Pivot的列,本质是把MENGE的具体值作为新表头,提取对应的PREIS值,这和我们需要的“按行顺序生成MENGE1、PREIS1这类固定列名”的逻辑完全不同。必须先通过行号标记每一行的位置,才能按位置转列。
内容的提问来源于stack exchange,提问作者ouboma
相关产品推荐
相关产品推荐

