我們有一個Projects表可以嵌套專案projectA.parent_id = projectB.id。
在選擇所有滿足給定條件的專案時,我們如何才能在兩者都滿足(或父滿足)的情況下僅選擇父項,如果子項滿足則僅選擇子項?
| ID | parent_id | is_chosen |
|---|---|---|
| 1 | 無效的 | 錯誤的 |
| 2 | 1 | 真的 |
| 3 | 2 | 真的 |
| 4 | 1 | 錯誤的 |
| 5 | 4 | 錯誤的 |
| 6 | 1 | 錯誤的 |
| 7 | 6 | 真的 |
| 8 | 1 | 真的 |
| 9 | 8 | 錯誤的 |
SELECT p.id
FROM "Projects" p
JOIN "Projects" parent
ON p.parent_id = p.id
WHERE is_chosen = true
AND ...
結果應該是2,7,8而不是2,3,7,8。3將被排除,因為它的父級2已被選中。
應該包括什么AND來實作這一點,還是應該對其進行重組?
uj5u.com熱心網友回復:
您可以合并兩個查詢,一個用于父母,一個用于孩子。例如:
select distinct *
from (
select p.* -- finding parents
from projects p
join projects c on c.parent_id = p.id
where p.is_chosen
union all
select c.* -- finding children
from projects p
join projects c on c.parent_id = p.id
where not p.is_chosen and c.is_chosen
) x
結果:
id parent_id is_chosen
--- ---------- ---------
2 1 t
8 1 t
7 6 t
請參閱db<>fiddle中的示例。
uj5u.com熱心網友回復:
應該可以簡化為:
SELECT p.id
FROM parents p
WHERE is_chosen = 'true'
AND NOT EXISTS (SELECT *
FROM parents p2
WHERE p2.is_chosen = 'true'
AND p2.id = p.parent_id)
uj5u.com熱心網友回復:
你可以像這樣使用 CTE
WITH CTE AS (
SELECT *
FROM tab
WHERE is_chosen
)
SELECT
id
FROM CTE t
WHERE NOT EXISTS (
SELECT
FROM CTE
WHERE id = t.parent_id
)
演示
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/498463.html
標籤:sql PostgreSQL
