2

使用SQL我試圖獲取用戶後代的id列表。所以,說我有:SQL遞歸CTE返回比預期更多的結果

Id | ManagerId | Name 
---|-----------|------ 
4 | NULL  | James Smith 
7 | 4   | John Doe (1) 
8 | 7   | John Doe (2) 
9 | 8   | John Doe (3) 
10 | 8   | John Doe (4) 

而我想找回4, 7, 8, 9, 10。在網上查看推薦的方法是創建一個遞歸CTE,我已經這樣做:

WITH UsersCTE AS (
    SELECT Id, 
      ManagerId 
    FROM Users 
    WHERE IsActive = 1 
    UNION ALL 
    SELECT A.Id, 
      UsersCTE.Id 
    FROM UsersCTE 
      INNER JOIN Users AS A 
       ON A.ManagerId = UsersCTE.ManagerId 
) 

SELECT * 
FROM UsersCTE; 

哪種作品。它通過獲得我想要的ID開始,然後就開始了,並以各種方式開始獲得IDS。我會承認,我不知道它是如何工作的,但它並沒有給我我想要的結果。相反,它給我:

enter image description here

我怎樣才能得到它給我正是我想要的ID。作爲參考,我需要得到這個列表,以便我可以查詢數據庫並獲取當前用戶和他們管理的任何後代的訂單列表。我正在使用EF6進行數據訪問,並計劃將此CTE放入視圖並進行適當查詢,但我願意提供更好的建議。

回答

2

重寫如下:

WITH UsersCTE AS (
    SELECT Id, 
      ManagerId 
    FROM Users 
    WHERE IsActive = 1 and ManagerID is null 
    UNION ALL 
    SELECT A.Id, 
      UsersCTE.Id 
    FROM UsersCTE 
      INNER JOIN Users AS A 
       ON A.ManagerId = UsersCTE.Id and A.IsActive = 1 
) 

SELECT * 
FROM UsersCTE; 

在第一部分的空濾錨您的CTE即給它沒有經理的員工的基本情況。另一個變化是第二部分的連接條件。更新的條件將經理ID與員工ID匹配。

Demo

+0

啊,我明白了。現在有道理。感謝您的幫助! – Gup3rSuR4c

+1

您可能想要在遞歸成員中重複WHERE IsActive = 1。 –

+0

當然,是的。早些時候超越它! –