2015-03-05 3 views
-1

У меня есть 2 таблицы, выглядит следующим образом:Несколько строк в более чем одного столбца в Oracle 11g

table1

id rs_id    
1 1001     
2 2001 

table2

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

Желаемые Выходные:

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

Может кто-то угодить Помогите?

+0

У вас есть максимальное число столбцов - это будет всегда быть 4? Или вы ищете динамическое решение? – sgeddes

+0

Что вы пробовали? Где у вас проблемы? – Degustaf

+0

Это всегда было 4. Я пытался сделать это с помощью функции listaggr – Tarun

ответ

2

Предполагая, что вы знаете количество столбцов, вы в основном пытаетесь получить pivot свои результаты. Один из вариантов - использовать условную агрегацию. Однако у вас нет поля для агрегирования.

Вот один подход, использующий 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 

Если вы не знаете, количество столбцов, вам необходимо использовать динамический SQL для создания списка.

0

Вот одно решение, которое будет работать для Oracle 10g, а также Oracle 11g. Я предполагаю, что ваше максимальное количество столбцов равно 4. Аналогичное решение можно разработать с помощью PIVOT; если вы хотите динамическое решение, вам нужно будет использовать 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; 
+1

Приятное время, выглядит знакомым ... – sgeddes

+0

это работает отлично ... спасибо тонну – Tarun

0

Первое решение:

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; 

Второе решение:

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 
); 
Смежные вопросы