如何在Snowflake中按customer_key透视前3订单的part_前缀列?
按Customer Key透视前3名订单的PART相关列
需求:按CUSTOMER_KEY对排名前3的订单中前缀为PART_的三列(PART_KEY、PART_QUANTITY、PART_AMOUNT)进行透视。
原始数据
| CUSTOMER_KEY | PART_KEY | PART_QUANTITY | PART_AMOUNT | TOP_ORDER_RANK |
|---|---|---|---|---|
| 10003 | 98909 | 39 | 74,408.10 | 1 |
| 10003 | 157096 | 49 | 56,501.41 | 2 |
| 10003 | 179085 | 42 | 48,891.36 | 3 |
| 10003 | 179075 | 10 | 28,891.36 | 4 |
预期结果
| CUSTOMER_KEY | PART_1_KEY | PART_1_QUANTITY | PART_1_AMOUNT | PART_2_KEY | PART_2_QUANTITY | PART_2_AMOUNT | PART_3_KEY | PART_3_QUANTITY | PART_3_AMOUNT |
|---|---|---|---|---|---|---|---|---|---|
| 10003 | 98909 | 39 | 74,408.10 | 157096 | 49 | 56,501.41 | 179085 | 42 | 48,891.36 |
示例数据(CTE)
WITH t1 AS ( SELECT '10003' AS CUSTOMER_KEY, '98909' AS PART_KEY, 39 AS PART_QUANTITY, 74408.10 AS PART_AMOUNT, 1 AS TOP_ORDER_RANK UNION ALL SELECT '10003' AS CUSTOMER_KEY, '157096' AS PART_KEY, 49 AS PART_QUANTITY, 56501.41 AS PART_AMOUNT, 2 AS TOP_ORDER_RANK UNION ALL SELECT '10003' AS CUSTOMER_KEY, '179085' AS PART_KEY, 42 AS PART_QUANTITY, 48891.36 AS PART_AMOUNT, 3 AS TOP_ORDER_RANK UNION ALL SELECT '10003' AS CUSTOMER_KEY, '179075' AS PART_KEY, 10 AS PART_QUANTITY, 28891.36 AS PART_AMOUNT, 4 AS TOP_ORDER_RANK )
实现方案
使用条件聚合实现透视,兼容大多数SQL引擎:
WITH t1 AS ( SELECT '10003' AS CUSTOMER_KEY, '98909' AS PART_KEY, 39 AS PART_QUANTITY, 74408.10 AS PART_AMOUNT, 1 AS TOP_ORDER_RANK UNION ALL SELECT '10003' AS CUSTOMER_KEY, '157096' AS PART_KEY, 49 AS PART_QUANTITY, 56501.41 AS PART_AMOUNT, 2 AS TOP_ORDER_RANK UNION ALL SELECT '10003' AS CUSTOMER_KEY, '179085' AS PART_KEY, 42 AS PART_QUANTITY, 48891.36 AS PART_AMOUNT, 3 AS TOP_ORDER_RANK UNION ALL SELECT '10003' AS CUSTOMER_KEY, '179075' AS PART_KEY, 10 AS PART_QUANTITY, 28891.36 AS PART_AMOUNT, 4 AS TOP_ORDER_RANK ) SELECT CUSTOMER_KEY, MAX(CASE WHEN TOP_ORDER_RANK = 1 THEN PART_KEY END) AS PART_1_KEY, MAX(CASE WHEN TOP_ORDER_RANK = 1 THEN PART_QUANTITY END) AS PART_1_QUANTITY, MAX(CASE WHEN TOP_ORDER_RANK = 1 THEN PART_AMOUNT END) AS PART_1_AMOUNT, MAX(CASE WHEN TOP_ORDER_RANK = 2 THEN PART_KEY END) AS PART_2_KEY, MAX(CASE WHEN TOP_ORDER_RANK = 2 THEN PART_QUANTITY END) AS PART_2_QUANTITY, MAX(CASE WHEN TOP_ORDER_RANK = 2 THEN PART_AMOUNT END) AS PART_2_AMOUNT, MAX(CASE WHEN TOP_ORDER_RANK = 3 THEN PART_KEY END) AS PART_3_KEY, MAX(CASE WHEN TOP_ORDER_RANK = 3 THEN PART_QUANTITY END) AS PART_3_QUANTITY, MAX(CASE WHEN TOP_ORDER_RANK = 3 THEN PART_AMOUNT END) AS PART_3_AMOUNT FROM t1 WHERE TOP_ORDER_RANK <=3 GROUP BY CUSTOMER_KEY;
逻辑说明
- 先通过
WHERE TOP_ORDER_RANK <=3过滤出前3名订单 - 针对每个排名(1-3),用
CASE语句提取对应的PART_KEY、PART_QUANTITY、PART_AMOUNT字段 - 最后按
CUSTOMER_KEY分组,用MAX聚合得到每个分组下各排名对应的字段值
内容的提问来源于stack exchange,提问作者kimi
相关产品推荐
相关产品推荐

