[英]Rows to columns in oracle sql for multiple rows
我在源表中有如下原始数据。 我需要这个转换如下所示。
用户身份 | domain_id | id_value | id_status |
---|---|---|---|
48085640 | ID1 | 21885688845 | 5 |
48085640 | ID1 | 20544518912 | 5 |
48085640 | ID2 | 176652329 | 5 |
48085640 | ID2 | 121702229 | 5 |
48085640 | ID3 | 111844976 | 5 |
48085640 | ID3 | 111347117 | 5 |
48085640 | ID4 | 1234567 | 5 |
我正在尝试实现 output 如下。 ID1、ID2、ID3 有两个值。 如果我使用 pivot,我必须使用聚合 function,例如 max() 或 min(),我将丢失其中一行。我还需要仅获取 ID1、ID2 和 ID3 并过滤 IDA8 的 Z65E8800B5C682A6AAD896F 的 Z65E8800B5C682A6AAD8ZFC。 请帮助我在 oracle sql 和黑斑羚中实现这一目标,如果可能的话
用户身份 | ID1 | ID2 | ID3 | id_status |
---|---|---|---|---|
48085640 | 218856888 | 1766523293 | 111844976 | 5 |
48085640 | 205445189 | 1217022297 | 111347117 | 5 |
您始终可以手动处理 pivot 此数据,然后将其加入每个 ID 的其efl。
我们试试看:
CREATE TABLE ABC_123 (
user_id NUMBER, domain_id varchar2(3), id_value NUMBER, id_status number );
begin
INSERT INTO ABC_123 values (48085640, 'ID1', 21885688845, 5);
INSERT INTO ABC_123 values (48085640, 'ID1', 20544518912 ,5);
INSERT INTO ABC_123 values (48085640, 'ID2', 176652329 ,5);
INSERT INTO ABC_123 values (48085640, 'ID2', 121702229 ,5);
INSERT INTO ABC_123 values (48085640, 'ID3', 111844976 ,5);
INSERT INTO ABC_123 values (48085640, 'ID3', 111347117 ,5);
INSERT INTO ABC_123 values (48085640, 'ID4', 1234567 ,5);
END;
COMMIT;
WITH pivot_data as
( SELECT user_id
, CASE WHEN domain_id = 'ID1' THEN id_value ELSE NULL END AS ID1
, CASE WHEN domain_id = 'ID2' THEN id_value ELSE NULL END AS ID2
, CASE WHEN domain_id = 'ID3' THEN id_value ELSE NULL END AS ID3
, row_number() over(PARTITION BY domain_id ORDER BY 1 /* order by is not important, but is mandatory*/ ) AS rownum_for_domain_id
, id_status
FROM ABC_123 )
SELECT d1.user_id, d1.ID1, d2.ID2, d3.ID3, d1.id_status
FROM pivot_data d1 /* inner for domain_id = 'ID1' - it determines number of rows */
LEFT JOIN pivot_data d2
ON d1.user_id = d2.user_id
AND d2.ID2 IS NOT NULL
AND d2.rownum_for_domain_id = d1.rownum_for_domain_id
LEFT JOIN pivot_data d3
ON d1.user_id = d3.user_id
AND d3.ID3 IS NOT NULL
AND d3.rownum_for_domain_id = d1.rownum_for_domain_id
WHERE d1.ID1 IS NOT null ;
用户身份 | ID1 | ID2 | ID3 | ID_STATUS |
---|---|---|---|---|
48085640 | 21885688845 | 176652329 | 111844976 | 5 |
48085640 | 20544518912 | 121702229 | 111347117 | 5 |
使用ROW_NUMBER
分析 function 根据每个user_id
/ domain_id
分区内的顺序为每一行指定一个数字,然后使用PIVOT
:
SELECT user_id,
id1,
id2,
id3,
id_status
FROM (
SELECT t.*,
ROW_NUMBER() OVER (PARTITION BY user_id, domain_id ORDER BY ROWNUM)
AS rn
FROM table_name t
)
PIVOT (
MAX(id_value)
FOR domain_id IN ('ID1' AS id1, 'ID2' AS id2, 'ID3' AS id3)
)
其中,对于样本数据:
CREATE TABLE table_name (user_id, domain_id, id_value, id_status) AS
SELECT 48085640, 'ID1', 21885688845, 5 FROM DUAL UNION ALL
SELECT 48085640, 'ID1', 20544518912, 5 FROM DUAL UNION ALL
SELECT 48085640, 'ID2', 176652329, 5 FROM DUAL UNION ALL
SELECT 48085640, 'ID2', 121702229, 5 FROM DUAL UNION ALL
SELECT 48085640, 'ID3', 111844976, 5 FROM DUAL UNION ALL
SELECT 48085640, 'ID3', 111347117, 5 FROM DUAL UNION ALL
SELECT 48085640, 'ID4', 1234567, 5 FROM DUAL;
输出:
用户身份 ID1 ID2 ID3 ID_STATUS 48085640 21885688845 176652329 111844976 5 48085640 20544518912 121702229 111347117 5
db<>在这里摆弄
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.