繁体   English   中英

多行的 oracle sql 中的行到列

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM