我需要构建一个查询,它应该给我下面提到的输出。
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
提前致谢
答案 0 :(得分: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
答案 1 :(得分:0)
由于levelA,levelB,levelC之间的关系不明确。我假设你想要返回max(name)以防相应的值不可用。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