2014-12-20 2 views
-1

Мне нужно построить запрос, который должен дать мне ниже упомянутого вывода.Запрос на получение

My table structure      Required output 

Depth | Name       Level A | Level B | Level C 
1  |A         A | B  | C 
2  |B         A1 | B1 | C1 
3  |C         A1 | B1 | C2 
1  |A1        A1 | B2 | C3 
2  |B1        A1 | B2 | C4 
3  |C1        
3  |C2 
2  |B2 
3  |C3 
3  |C4 

Заранее спасибо

+2

можете ли вы объяснить логику, используемую для получения такого результата? – Mureinik

+0

, какую версию oracle db вы используете ... –

+0

Что вы пробовали до сих пор и почему вы ожидаете/требуете выхода? Кажется, нет никакой очевидной связи между вашим входом и выходом, кроме того, что это те же буквы ... – Malhelo

ответ

1

Учитывая ваши конкретные данные, вы можете приблизиться с:

select a.name as levela, b.name as levelb, c.name as levelc 
from (select name, row_number() over (order by id) as seqnum from table where depth = 1 
    ) a full outer join 
    (select name, row_number() over (order by id) as seqnum from table where depth = 2 
    ) b full outer join 
    on b.seqnum = a.seqnum 
    (select name, row_number() over (order by id) as seqnum from table where depth = 3 
    ) c 
    on c.seqnum = coalesce(a.seqnum, b.seqnum); 

NULL Это вставляет сек вместо того чтобы повторять финальные значения для трех столбцов. Если вы хотите, чтобы конечные значения, это должно работать:

select coalesce(a.name, maxes.a) as levela, 
     coalesce(b.name, maxes.b) as levelb, 
     coalesce(c.name, maxes.c) as levelc 
from (select name, row_number() over (order by id) as seqnum from table where depth = 1 
    ) a full outer join 
    (select name, row_number() over (order by id) as seqnum from table where depth = 2 
    ) b full outer join 
    on b.seqnum = a.seqnum 
    (select name, row_number() over (order by id) as seqnum from table where depth = 3 
    ) c 
    on c.seqnum = coalesce(a.seqnum, b.seqnum) cross join 
    (select max(case when depth = 1 and id = maxid then name end) as max_a, 
      max(case when depth = 2 and id = maxid then name end) as max_b, 
      max(case when depth = 3 and id = maxid then name end) as max_c 
     from (select t.*, 
        max(id) over (partition by depth) as maxid 
      from t 
      ) t 
    ) maxes 
+0

hii @gordan, что здесь id здесь в этом вопросе ??? –

+1

@Abhishekchoudhary. , , «У меня есть столбец с уникальным порядковым номером и в моей исходной таблице». Я назвал эту колонку 'id'. –

0

Поскольку отношения между levelA, уровень Ъ, levelC не clear.I предположили, вы хотите, чтобы вернуть макс (имя) в случае, если соответствующее значение не available.The Sql Fiddle here .Вы может заменить order by my_table.name в order by unique_seq_column а также max(name) name по name value in max(unique_seq_column), если это удовлетворяет ваше требование

--Get the max count and max name for each level 
with cnt_max1 as (select max(name) name ,count(1) cnt from my_table where depth=1) 
     ,cnt_max2 as (select max(name) name ,count(1) cnt from my_table where depth=2) 
    ,cnt_max3 as (select max(name) name ,count(1) cnt from my_table where depth=3) 

--find out the total rows required 

,greatest_cnt as (select greatest(cnt_max1.cnt,cnt_max2.cnt,cnt_max3.cnt) cnt from cnt_max1,cnt_max2,cnt_max3) 

--Establish relationship between levelA,levelB,levelC using sublevel column 

,level_A as (select * from (select rownum sublevel, my_table.name as levela from my_table where depth=1 order by my_table.name) 
      union 
      select level+cnt_max1.cnt sublevel,cnt_max1.name levela 
        from cnt_max1,greatest_cnt connect by level <=(greatest_cnt.cnt - cnt_max1.cnt)) 

,level_B as (select * from (select rownum sublevel, my_table.name as levelb from my_table where depth=2 order by my_table.name) 
      union 
      select level+cnt_max2.cnt sublevel,cnt_max2.name levelb 
      from cnt_max2,greatest_cnt connect by level <=(greatest_cnt.cnt - cnt_max2.cnt)) 

,level_C as (select * from (select rownum sublevel, my_table.name as levelc from my_table where depth=3 order by my_table.name) 
      union 
      select level+cnt_max3.cnt sublevel,cnt_max3.name levelc 
      from cnt_max3,greatest_cnt connect by level <=(greatest_cnt.cnt - cnt_max3.cnt)) 

--Display the data 

select levela,levelb,levelc 
from level_A join level_b 
on level_A.sublevel=level_B.sublevel 
join level_c on level_C.sublevel=level_b.sublevel 
+1

он не будет работать, поскольку предложение pivot требует агрегатной функции .... также @abhishek использует oracle 10g –

+1

@DharmeshPorwal предоставил пользовательское решение сейчас – psaraj12

Смежные вопросы