查询检索

时间:2014-12-20 10:56:58

标签: sql oracle oracle10g

我需要构建一个查询,它应该给我下面提到的输出。

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 个答案:

答案 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