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

当然,是的。早些时候超越它! –