简体   繁体   English

在Oracle 11g中多行到多于一列

[英]Multiple rows in to more than one column in oracle 11g

I have 2 tables that looks like this: 我有2张桌子,看起来像这样:

table1 表格1

id  rs_id               
1   1001                
2   2001

table2 表2

rs_id   rs_name             
1001    aaa             
1001    bbb             
2001    aaa             
2001    bbb             
2001    ccc     

Desired Output: 所需输出:

id  rs_id   rs_name1    rs_name2    rs_name3    rs_name4
1   1001    aaa         bbb     
2   2001    aaa         bbb         ccc 

Can someone please help? 有人可以帮忙吗?

Assuming you know the number of columns, you are basically trying to pivot your results. 假设你知道的列数,你基本上是试图pivot你的结果。 One option is to use conditional aggregation. 一种选择是使用条件聚合。 However, you don't have a field to aggregate on. 但是,您没有要汇总的字段。

Here's one approach using row_number() to create such a field: 这是一种使用row_number()创建此类字段的方法:

select id, 
    rs_id, 
    max(case when rn = 1 then rs_name end) rs_name_1,
    max(case when rn = 2 then rs_name end) rs_name_2,
    max(case when rn = 3 then rs_name end) rs_name_3,
    max(case when rn = 4 then rs_name end) rs_name_4
from (
    select t1.id, 
          t1.rs_id, 
          t2.rs_name, 
          row_number() over (partition by t1.id, t1.rs_id order by t2.rs_name) rn
    from table1 t1
        join table2 t2 on t1.rs_id = t2.rs_id
) t
group by id, rs_id

If you don't know the number of columns, you'll need to use dynamic sql to build the list. 如果您不知道列数,则需要使用动态sql来构建列表。

Here is one solution that will work for Oracle 10g as well as Oracle 11g. 这是一个适用于Oracle 10g和Oracle 11g的解决方案。 I'm assuming that your maximum number of columns is 4. A similar solution can be worked out with PIVOT ; 我假设您的最大列数为4。可以使用PIVOT解决类似的解决方案; if you want a dynamic solution then you'll need to use PL/SQL. 如果需要动态解决方案,则需要使用PL / SQL。

SELECT id, rs_id
     , MAX(CASE WHEN rn = 1 THEN rs_name END) AS rs_name1
     , MAX(CASE WHEN rn = 2 THEN rs_name END) AS rs_name2
     , MAX(CASE WHEN rn = 3 THEN rs_name END) AS rs_name3
     , MAX(CASE WHEN rn = 4 THEN rs_name END) AS rs_name4
  FROM (
    SELECT t1.id, t1.rs_id, t2.rs_name, ROW_NUMBER() OVER ( PARTITION BY t1.id ORDER BY t2.rs_name ) AS rn
      FROM table1 t1 INNER JOIN table2 t2
        ON t1.rs_id = t2.rs_id
) GROUP BY id, rs_id;

First Solution: 第一个解决方案:

SELECT id, rs_id
     , MAX(CASE WHEN rn = 1 THEN rs_name END) AS rs_name1
     , MAX(CASE WHEN rn = 2 THEN rs_name END) AS rs_name2
     , MAX(CASE WHEN rn = 3 THEN rs_name END) AS rs_name3
     , MAX(CASE WHEN rn = 4 THEN rs_name END) AS rs_name4
  FROM (
    SELECT t1.id, t1.rs_id, t2.rs_name, ROW_NUMBER() OVER ( PARTITION BY t1.id ORDER BY t2.rs_name ) AS rn
      FROM table1 t1 INNER JOIN table2 t2
        ON t1.rs_id = t2.rs_id
) GROUP BY id, rs_id;

Second Solution: 第二种解决方案:

SELECT  id, rs_id,
        REGEXP_SUBSTR (rsname_list, '[^,]+', 1, 1)    AS rs_name1,
        REGEXP_SUBSTR (rsname_list, '[^,]+', 1, 2)    AS rs_name2,
        REGEXP_SUBSTR (rsname_list, '[^,]+', 1, 3)    AS rs_name3,
        REGEXP_SUBSTR (rsname_list, '[^,]+', 1, 4)    AS rs_name4
FROM
(
SELECT a.id,
       a.rs_id,
       LISTAGG (
          b.rs_name, ','
       ) WITHIN GROUP (
          ORDER BY b.rs_name
       ) AS rsname_list
  FROM test_table1 a
  LEFT JOIN test_table2 b ON a.rs_id = b.rs_id
 GROUP BY a.id,a.rs_id
 ORDER BY a.rs_id
 );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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