簡體   English   中英

SQL 父子順序

[英]SQL Order by parent and child

基本上我需要在這里查詢幫助。 我想按正確的順序排列,即孩子必須在父母的名字下並按 AZ 順序排列。 但是如果我在 child ( Split 1 ) 下添加一個subChild似乎順序是錯誤的。 它應該在Room Rose

p/s : 一個 subChild 也可以創建另一個 subChild

在這里我提供一個演示

感謝您幫助我正確訂購?

SELECT A.venueID
     , B.mainVenueID
     , A.venueName 
  FROM tblAdmVenue A 
  LEFT 
  JOIN tblAdmVenueLink B
    ON A.venueID = B.subVenueID
 ORDER   
    BY COALESCE(B.mainVenueID, A.venueID)
     , B.mainVenueID IS NOT NULL
     , A.venueID

在此處輸入圖片說明

我希望它返回這樣的訂單。

venueName
--------------
Banquet
Big Room
-Room Daisy
-Room Rose
  -Split 1
Hall
-Meeting Room WP

似乎這種遞歸方法也不起作用

WITH venue_ctg AS (
  SELECT A.venueID, A.venueName, B.mainVenueID 
  FROM tblAdmVenue A LEFT JOIN tblAdmVenueLink B
  ON A.venueID = B.subVenueID
  WHERE B.mainVenueID IS NULL 

  UNION ALL

  SELECT A.venueID, A.venueName, B.mainVenueID 
  FROM tblAdmVenue A LEFT JOIN tblAdmVenueLink B
  ON A.venueID = B.subVenueID
  WHERE B.mainVenueID IS NOT NULL
)
SELECT *
FROM venue_ctg ORDER BY venueName

給出的輸出

在此處輸入圖片說明

對於您的數據,您可以使用它:要正確顯示它,您可以使用像逗號這樣的 SEPARAPR,並拆分返回的數據,並檢查層次結構

-- schema CREATE TABLE tblAdmVenue ( venueID VARCHAR(225) NOT NULL, venueName VARCHAR(225) NOT NULL, PRIMARY KEY(venueID) ); CREATE TABLE tblAdmVenueLink ( venueLinkID VARCHAR(225) NOT NULL, mainVenueID VARCHAR(225) NOT NULL, subVenueID VARCHAR(225) NOT NULL, PRIMARY KEY(venueLinkID) -- FOREIGN KEY (DepartmentId) REFERENCES Departments(Id) ); -- data INSERT INTO tblAdmVenue (venueID, venueName) VALUES ('LA43', 'Big Room'), ('LA44', 'Hall'), ('LA45', 'Room Daisy'), ('LA46', 'Room Rose'), ('LA47', 'Banquet'), ('LA48', 'Split 1'), ('LA49', 'Meeting Room WP'); INSERT INTO tblAdmVenueLink (venueLinkID, mainVenueID, subVenueID) VALUES ('1', 'LA43', 'LA45'), ('2', 'LA43', 'LA46'), ('3', 'LA46', 'LA48'), ('4', 'LA44', 'LA49');
\n \n\n \n\n \n\n \n
with recursive cte (subVenueID, mainVenueID,level) as ( select subVenueID, mainVenueID, 1 as level from tblAdmVenueLink union select p.subVenueID, cte.mainVenueID, cte.level+1 from tblAdmVenueLink p inner join cte on p.mainVenueID = cte.subVenueID ) select CONCAT(GROUP_CONCAT(b.venueName ORDER BY level DESC SEPARATOR '-->') ,'-->',a.venueName) from cte c LEFT JOIN tblAdmVenue a ON a.venueID = c.subVenueID LEFT JOIN tblAdmVenue b ON b.venueID = c.mainVenueID GROUP BY subVenueID;
\n |  CONCAT(GROUP_CONCAT(b.venueName ORDER BY level DESC SEPARATOR '-->') ,'-->',a.venueName) |\n |  :------------------------------------------------- ---------------------------------------- |\n | 大房間-->房間雛菊 |\n | 大房間-->玫瑰房間 |\n |  Big Room-->Room Rose-->Split 1 |\n | 大廳-->會議室WP |\n

db<> 在這里擺弄

只使用一張桌子,而不是兩張。 第一個表包含所有需要的信息。

然后使用WHERE mainVenueID IS NULL行開始 CTE,不需要JOIN

這可能是一個很好的教程: https : //stackoverflow.com/a/18660789/1766831

它的“森林”接近你想要的。

我想你有:

  1. 表 tblAdmVenue A 是會場列表;
  2. table tblAdmVenueLink B 是父子樹關系表

對於您關於如何獲得正確排序順序的問題,我認為其中一個技巧是連接父場地名稱。

with q0(venueID, venueName, mainVenueID, venuePath) as (
  select
    A.venueID,
    A.venueName,
    null,
    A.venueName
  from tblAdmVenue A
       left join tblAdmVenue B on A.venueID = B.subVenueID
  where B.mainVenueID is null
  union all
  select
    A.venueID,
    A.venueName,
    q0.venueID,
    q0.venuePath + char(9) + A.venueName
  from q0
       inner join tblAdmVenue B on q0.venueID = B.mainVenueID
       inner join tblAdmVenue A on A.venueID = B.subVenueID
)
select venueID, venueName, mainVenueID
from q0
order by venuePath

您希望首先按字母順序和深度對數據進行排序。

一個常見的解決方案是從頂部元素遍歷結構,在你走的時候連接到每個項目的路徑。 然后您可以直接使用該路徑進行排序。

以下是如何在 MySQL 8.0 中使用遞歸查詢執行此操作

with recursive cte(venueID, venueName, mainVenueID, path, depth) as (
    select v.venueID, v.venueName, cast(null as char(100)), venueName, 0
    from tblAdmVenue v
    where not exists (select 1 from tblAdmVenueLink l where l.subVenueID = v.venueID)
    union all
    select v.venueID, v.venueName, c.venueID, concat(c.path, '/', v.venueName), c.depth + 1
    from cte c
    inner join tblAdmVenueLink l on l.mainVenueID = c.venueID
    inner join tblAdmVenue v on v.venueID = l.subVenueID
)
select * from cte order by path

遞歸查詢的錨點選擇頂級節點(即鏈接表的subVenueID列中不存在id 的行)。 然后,遞歸部分遵循關系。

作為獎勵,我添加了一個level列來表示每個節點的深度,頂部節點從 0 開始。

DB Fiddle 上的演示

venueID | venueName       | mainVenueID | path                       | depth
:------ | :-------------- | :---------- | :------------------------- | ----:
LA47    | Banquet         | null        | Banquet                    |     0
LA43    | Big Room        | null        | Big Room                   |     0
LA45    | Room Daisy      | LA43        | Big Room/Room Daisy        |     1
LA46    | Room Rose       | LA43        | Big Room/Room Rose         |     1
LA48    | Split 1         | LA46        | Big Room/Room Rose/Split 1 |     2
LA44    | Hall            | null        | Hall                       |     0
LA49    | Meeting Room WP | LA44        | Hall/Meeting Room WP       |     1

暫無
暫無

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

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