如何仅查询前三个参考 ID 以及我如何查询直到低于 3 个级别的组仅基于参考 ID

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

我在下面有这样的 table,它保存所有具有参考 ID 的数据:-

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

首先我需要一些查询,我可以在其中扫描哪些是前三个参考 ID 级别并显示。

--- 例子:当D加在C下面时---

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

结果(从下到上):A、B 和 C 是 D 的前三个引用 ID 结果(从上到下):A 将 B、C 和 D 作为 child 基于 refid

当 E 进入 D 下面时,A 不是 E 的有效参考 ID。我需要显示 E 的前三个参考 ID。

--- 例子:当E加在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)

结果(从下到上):D、C 和 B 是 E 的前三个参考 ID 结果(从上到下):B 有 C、D 和 E 作为 child 基于 refid

作为最终结果,我需要为每个 ID 重新排列和存储我的计算视图,直到组级别 3,如下所示:-

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

谁遇到过这个问题请帮我解决一下。无论如何,提前感谢您阅读这个问题。

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

输出:

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     |

不确定我是否理解 F 会发生什么。此外,在您想要的输出中看不到 'E null' 行背后的任何逻辑

Postgreql 版本(|| 而不是用于连接和引用级别别名的“+”):

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

鲁道夫·尤根森。

首先,非常感谢您给出的解决方案。

我在下面附上你的解决方案的输出:-

Result: View Group Level

我看到 ID A 为 B 打印了两次,正如您在我的附件中看到的那样,其他人是完美的基于生成序列组级别的 refid。您认为是因为我开始键入其他数据还是我们需要更改您所做的一些查询?

"It's unreadable. – Rudolf Yurgenson"

好的。现在我需要创建查询以获得此结果:-

-- 例子:当E加在D下面时---

GLevel Id RefID No 开始A
级别(1) B (A) (3) 等级(2) C (B) (2) 等级(3) D (C) (1) 等级(4) E (D)

当我像“...... Where ID='D'”这样查询时,我得到了结果C ,B,A只能列出3级。 如果我选择“.... Where ID='C'”,这是相同的过程,结果应该只显示 B 和 A。因为上面A没有数据。 如果我选择“...... Where ID='E'”,结果应该会有所不同,其中 A 未列出,结果应该仅为 D、C 和 B。

我想使用 SELECT TOP(3),但我仍然没有想到要写它。

所以,你已经逆向了输出祖先的任务。

这是一个简单的查询,returns 列中的前三个祖先(第一个是 parent 等):

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

结果是:

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

修改后的枢轴版本:

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

结果:

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