簡體   English   中英

MySQL - 從分層表中獲取特定類型的孩子

[英]MySQL - get children of a specific type from a hierarchical table

我有兩個表,Groups 和 GroupHierarchy。 他們有以下數據。

團體:

id   |  Name      | type

8    |  M.Sc      | degree  
4    |  prog1     | programme   
5    |  prog2     | programme   
1    |  class1    | class   
3    |  class2    | class

組層次結構:

parentGroupId | childGroupId

8             | 4

8             | 5

4             | 1

5             | 3

類型程序的 prog1、prog2 是碩士學位的孩子。

我想執行以下查詢。 給定父組 ID 和所需的組類型,查詢應返回直接或間接屬於父組的所需類型的所有記錄。

eg 1: Parent Group Id = 8, type = program returns records 8 | 4 和 8 | 5.說明:prog1(4)和prog2(5)是msc degree(8)下的programs

例2:Parent Group Id = 8, type = class 返回記錄4 | 1 和 5 | 3.說明:class1(1)和class2(3)是msc degree(8)下的classes

如何構建返回上述結果的查詢?

您可以使用遞歸 CTE 檢索子弧,然后組裝子節點列表,最后按類型過濾。

例如:

with recursive
p as (select 8 as id, 'programme' as type),
r as (select h.* from h cross join p where h.parentGroupId = p.id),
n as (
  select * from r
 union all
  select h.*
  from n
  join h on h.parentGroupId = n.childGroupId
)
select g.*
from (
  select childGroupId as id from n
  union all select distinct parentGroupId from r
) a
join g on g.id = a.id
join p on p.type = g.type;

結果:

 id  name   type      
 --- ------ --------- 
 4   prog1  programme 
 5   prog2  programme 

並通過更改第二行中的參數:

with recursive
p as (select 8 as id, 'class' as type),
r as (select h.* from h cross join p where h.parentGroupId = p.id),
n as (
  select * from r
 union all
  select h.*
  from n
  join h on h.parentGroupId = n.childGroupId
)
select g.*
from (
  select childGroupId as id from n
  union all select distinct parentGroupId from r
) a
join g on g.id = a.id
join p on p.type = g.type

結果:

 id  name    type  
 --- ------- ----- 
 1   class1  class 
 3   class2  class 

請參閱DB Fiddle中的運行示例。

編輯 - 查詢說明

該查詢包括三個 CTE:

  • p CTE 定義參數。
  • r CTE 選擇起始節點的所有子節點。
  • n CTE 向下遍歷樹並選擇子項的所有子項,依此類推。
  • 最后,主查詢檢索每個節點的類型,並根據它進行過濾。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM