![](/img/trans.png)
[英]SQL Query to get records of parent table that have a list of child records
[英]How to Order table records with parent followed by child using SQL Query
我有一個包含幾條記錄的表,其父記錄如下所示。 並非所有人都有父記錄。
id | parent_id
--------------
1 | 0
2 | 0
3 | 1
4 | 0
5 | 0
6 | 0
7 | 5
我希望記錄與父母和孩子一起訂購:
id | parent_id
--------------
1 | 0
3 | 1
2 | 0
4 | 0
5 | 0
7 | 5
6 | 0
如何在不使用存儲過程的情況下使用 SQL 查詢來實現這一點?
我正在使用 postgres。
假設您的示例暗示了可能存在的層次結構恰好是一個層次:
SELECT child.*
FROM tbl AS child
LEFT JOIN tbl AS parent ON parent.id = child.parent_id
ORDER BY COALESCE(parent.id, child.id) -- order by parent if exists
, parent.id IS NOT NULL -- parent first per group
, child.id; -- order rest by id
僅當我們通過一些其他屬性(例如“名稱”)進行排序時才需要連接(這是典型的情況,因為代理ID的值沒有意義)。 盡管僅像您演示的那樣按ID排序,但是我們不需要聯接,因為所有信息都已經存在(就像戈登演示的那樣)。 然后我們可以簡化:
SELECT *
FROM tbl
ORDER BY CASE WHEN parent_id = 0 THEN id ELSE parent_id END
, parent_id <> 0
, id;
ORDER BY
項在其子級之前對父級進行排序。 有效,因為FALSE
在TRUE
之前排序。 看到:
ORDER BY
項。 db <> fiddle 這里 -具有擴展的測試用例,以演示ORDER BY
項目的相關性。
您需要一個包含所有級別的根ID的遞歸查詢 ,然后可以按以下順序對行進行排序:
with recursive entries as (
select id, parent_id, id as root_id, 1 as level
from the_table
where parent_id = 0 -- this should be IS NULL
union all
select c.id, c.parent_id, p.root_id, p.level + 1
from the_table c
join entries p on p.id = c.parent_id
)
select id, parent_id
from entries
order by root_id, level, id;
在線示例: https : //rextester.com/YKUJ56922
我想你要:
order by coalesce(nullif(parent_id, 0), id), id
基本上,忽略parent_id
的零。 然后使用parent_id
如果存在),否則使用id
。
這是db <>小提琴。
此版本假定父ID小於子ID-這在您的數據中是正確的,並且在大多數情況下是有意義的。 如果要明確說明訂購順序:
order by coalesce(nullif(parent_id, 0), id),
(parent_id = 0) desc,
id
我用這種方式(Postgres):
SELECT id, parent_id, name
FROM my_table
ORDER BY
COALESCE(parent_id,id)||id::varchar
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.