How To Query Top Three Reference ID only and How I can query until 3 Level Group below only Based Reference ID

Deadly 提交于 2019-12-13 05:38:21

问题


I have table like this below where it save all data with reference id :-

ID  Name    RefID
A   AAAA    null
B   BBBB    A
C   CCCC    B
D   DDDD    C
E   EEEE    D
F   FFFF    E

Firstly I need some query where I can scan which are the top three reference id level only and show up.

--- Example: When D added below C ---

GLevel  ID  RefID   No
Start   A       (3)
Level(1)    B   (A) (2)     
Level(2)    C   (B) (1)
Level(3)   D    (C)

Result (Down To Top): A,B and C are top three reference id for D Result (Top to Down): A have B,C and D as child based refid

When E has enter below D, then A are not valid reference id for E. I need to show top three reference id for E.

--- Example: When E added below D ---

GLevel  Id  RefID   No
Start   A   
Level(1)    B   (A) (3)
Level(2)    C   (B) (2)
Level(3)   D    (C) (1)
Level(4)   E    (D)

Result (Down To Top): D,C and B are top three reference id for E Result (Top to Down): B have C,D and E as child based refid

As a final result I need to rearrange and store my compute view for each ID till Group Level 3 only like below:-

id  GroupLevel  RefID   
A   Level(1)        B   
A   Level(2)        C
A   Level(3)        D
B   Level(1)        C
B   Level(2)        D
B   Level(3)        E
C   Level(1)        D
C   Level(2)        E
D   Level(1)        E
E   null

Who have cross this problem please help me how to solve it. Anyway thanks on advance for reading this question.


回答1:


Postgreql version (|| instead of '+' for concatenation and quoted level alias):

select ID, 'Level(' || cast(level as varchar(255)) || ')', RefID from (
    select t0.ID, 
    case level.level
        when 1 then t1.ID
        when 2 then t2.ID
        when 3 then t3.ID 
    end RefID,
    level.level
    from Test t0
    left outer join Test t1 on t1.RefID = t0.ID
    left outer join Test t2 on t2.RefID = t1.ID
    left outer join Test t3 on t3.RefID = t2.ID
    cross join (
        select 1 "level" union all
        select 2 union all
        select 3
    ) level
) t
where t.RefID is not null



回答2:


create table Test(
  ID varchar(10),
  Name varchar(10),
  RefID varchar(10)
)

insert into Test
select 'A','AAAA',null union all
select 'B','BBBB','A' union all
select 'C','CCCC','B' union all
select 'D','DDDD','C' union all
select 'E','EEEE','D' --union all
--select 'F','FFFF','E'

select ID, 'Level(' + cast(level as varchar(255)) + ')' GroupLevel, RefID from (
  select t0.ID, 
    case level.level
      when 1 then t1.ID
      when 2 then t2.ID
      when 3 then t3.ID 
    end RefID,
    level.level
  from Test t0
    left outer join Test t1 on t1.RefID = t0.ID
    left outer join Test t2 on t2.RefID = t1.ID
    left outer join Test t3 on t3.RefID = t2.ID
    cross join (
      select 1 level union all
      select 2 union all
      select 3
    ) level
) t
where t.RefID is not null

Output:

ID | GroupLevel | RefID |
---+------------+-------+
A  | Level(1)   | B     |
A  | Level(2)   | C     |
A  | Level(3)   | D     |
B  | Level(1)   | C     |
B  | Level(2)   | D     |
B  | Level(3)   | E     |
C  | Level(1)   | D     |
C  | Level(2)   | E     |
D  | Level(1)   | E     |

Not sure that I understand what should happen with F. Also, can't see any logic behind 'E null' row in your desired output




回答3:


Rudolf Yurgenson.

Firstly, thanks you so much for your solution given.

I attach the output from your solution below:-

Result: View Group Level

I saw ID A print twice for B as you can see on my attachment others are perfect generating sequence group level based refid. Do you think because I start key-in others data or we need to change a little bit of query you have make?.

"It's unreadable. – Rudolf Yurgenson"

Ok. Now I need to create query where I can get this result:-

-- Example: When E added below D ---

GLevel Id RefID No Start A
Level(1) B (A) (3) Level(2) C (B) (2) Level(3) D (C) (1) Level(4) E (D)

When I query like "...... Where ID='D' " I get a result C,B and A where 3 level only can listed. It's same process if i choose ".... Where ID='C' " the result should be show B and A only. Because above A has no data. The result should be different if I choose "...... Where ID='E' " where A are not listed and result should be D,C and B only.

I think using SELECT TOP(3) but still idea not on my head to write it.




回答4:


So, you have reversed task that outputs ancestors.

This is a simple query that returns first three ancestors (first one is a parent and etc.) in columns:

select t0.ID, t1.ID ancestor1, t2.ID ancestor2, t3.ID ancestor3
from Test t0
left outer join Test t1 on t0.RefID = t1.ID
left outer join Test t2 on t1.RefID = t2.ID
left outer join Test t3 on t2.RefID = t3.ID

Result is:

|ID|Ancestor1|Ancestor2|Ancestor3|
+--+---------+---------+---------+
|A |NULL     |NULL     |NULL     |
|B |A        |NULL     |NULL     |
|B1|A        |NULL     |NULL     |
|B2|A        |NULL     |NULL     |
|B4|A        |NULL     |NULL     |
|C |B        |A        |NULL     |
|C1|B        |A        |NULL     |
|D |C        |B        |A        |
|E |D        |C        |B        |
|F |E        |D        |C        |

Modified pivot version:

select ID, level, ancestor from (
  select distinct
    t0.ID,
    case level.level
      when 1 then t1.ID
      when 2 then t2.ID
      when 3 then t3.ID
    end ancestor, level
  from Test t0
  left outer join Test t1 on t0.RefID = t1.ID
  left outer join Test t2 on t1.RefID = t2.ID
  left outer join Test t3 on t2.RefID = t3.ID
  cross join (
    select 1 as level union all
    select 2 union all
    select 3
  ) level
) t where t.ancestor is not null
order by 1, 2

Result:

ID Level Ancestor
B   1   A
B1  1   A
B2  1   A
B4  1   A
C   1   B
C   2   A
C1  1   B
C1  2   A
D   1   C
D   2   B
D   3   A
E   1   D
E   2   C
E   3   B
F   1   E
F   2   D
F   3   C


来源:https://stackoverflow.com/questions/35171909/how-to-query-top-three-reference-id-only-and-how-i-can-query-until-3-level-group

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!