假設我有下表:
ID | Name | Active | ParentID
1 | Foo1 | 1 | 0
2 | Foo2 | 1 | 1
3 | Foo3 | 1 | 2
4 | Foo4 | 1 | 3
5 | Foo5 | 1 | 3
6 | Foo6 | 0 | 5
7 | Foo7 | 1 | 2
7 | Foo7 | 1 | 6
8 | Foo8 | 1 | 7
9 | Foo9 | 1 | 5
(我確實有重復的ID,我在上面表達了我的想法但沒有結果)
如您所見,一個孩子可以有多個父母。ParentID 為 0 的 ID 沒有父級。我需要選擇所有處于活動狀態且在其上方沒有非活動父級的 ID,無論在樹中的位置有多高。
因此,使用上面的資料集,我的結果將是:
ID | Name |
1 | Foo1 |
2 | Foo2 |
3 | Foo3 |
4 | Foo4 |
5 | Foo5 |
9 | Foo9 |
- ID 6 已被洗掉,因為它處于非活動狀態
- ID 7 被洗掉,因為它的父母之一 (6) 處于非活動狀態
- ID 8 被洗掉,因為其父級 (7) 的父級 (6) 處于非活動狀態
- ID 9 很好,因為它的父母 (5) 是活躍的,他的父母 5 也是如此等等
我在 where 中嘗試了一個子查詢
SELECT *
FROM table
WHERE ID not in (SELECT ID FROM table where Active = 0)
但這只能解決當前記錄的問題。
我也嘗試過用于員工/經理的典型自加入,但這只會深入一層,而在這里我還需要檢查父級的父級等
有什么建議/想法嗎?
uj5u.com熱心網友回復:
一種方法是使用 rCTE 來處理層次結構,并使用保留初始 ID 的列。然后您可以使用 anEXISTS來確保沒有值為0for 的行Active:
WITH rCTE AS(
SELECT ID,
Name,
Active,
ParentID,
ID AS InitialID
FROM dbo.YourTable YT
UNION ALL
SELECT YT.ID,
YT.Name,
YT.Active,
YT.ParentID,
r.InitialID
FROM rCTE r
JOIN dbo.YourTable YT ON r.ParentID = YT.ID)
SELECT *
FROM dbo.YourTable YT
WHERE NOT EXISTS (SELECT 1
FROM rCTE r
WHERE r.InitialID = YT.ID
AND r.Active = 0);
uj5u.com熱心網友回復:
我將使用遞回 CTE 來識別鏈是連續的 ID,使用條件和無條件增量 1,如下所示:
With A As
(Select ID, [Name], Active, ParentID, 0 As NUM_1, 0 As NUM_2
From Tbl Where ParentID=0
Union All
Select Tbl.ID, Tbl.[Name], Tbl.Active, Tbl.ParentID,
NUM_1 1 As NUM_1,
NUM_2 IIF(Tbl.Active=1,1,0) As NUM_2
From Tbl Inner Join A On (Tbl.ParentID=A.ID)
)
Select ID, [Name]
From A
Where ID Not In (Select ID From A Where NUM_1<>NUM_2)
Order by ID
結果:
| ID | 名稱 |
|---|---|
| 1 | Foo1 |
| 2 | Foo2 |
| 3 | Foo3 |
| 4 | Foo4 |
| 5 | Foo5 |
| 9 | Foo9 |
db<>小提琴
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/408479.html
標籤:
上一篇:如何從sql中的表中獲取最小值
