带有两个表的 SQL 递归 CTE

标签 sql sqlite recursion common-table-expression

试图围绕递归 CTE 进行思考,但遇到了一些麻烦。我有两张 table ,一张给员工,一张给部门。我正在尝试编写一个递归 CTE,它从一个锚定部门开始并遍历所有子部门,将一组具有外键的员工返回给锚定部门或任何子部门。

这是员工表的简化版本

employeeID     name               departmentID
1              Brad Fisher        1
2              Alex McCabe        2
3              Amy Calvin         2
4              Daniel Struthers   4

还有部门表。 parentID 只是指同一张表中的其他部门。
departmentID    name                      parentID
1               Company Operations        0
2               Guest Services            1
3               Staff Services            1
4               IT Support                3

下面是我整理的 CTE。只要在部门层次结构的每个级别中至少有一名员工,它将返回从顶部开始的所有员工的完整列表。但问题是,如果层次结构中有一个没有员工的部门,它会破坏那里的递归。
WITH EmployeeDepartmentHierarchy(employeeID, name, departmentID)
AS (
   SELECT e.employeeID,
          e.name,
          e.departmentID
   FROM Departments AS d
   INNER JOIN Employees AS e ON d.departmentID = e.departmentID
   WHERE d.name = "Company Operations"
   UNION ALL
   SELECT e.employeeID,
          e.name,
          d.deparmentID
   FROM Departments AS d
   INNER JOIN EmployeeDepartmentHierarchy AS edh ON edh.departmentID = d.parentID
   LEFT JOIN Employees AS e ON d.departmentID = e.departmentID
   )
   SELECT * FROM EmployeeDepartmentHierarchy

我正在尝试修复它,以便它将沿着整个部门层次结构向下移动,并且仅在没有找到子部门时终止,而不是在到达没有员工的部门时终止。

最佳答案

wildplasser已经评论过,在 CTE 中获取没有员工的部门,然后在外部查询中加入它们。

WITH dh
     (departmentid)
AS
(
SELECT d.departmentid
       FROM departments d
       WHERE d.name = 'Company Operations'
UNION ALL
SELECT d.departmentid
       FROM departments d
            INNER JOIN dh
                       ON dh.departmentid = d.parentid
)
SELECT e.employeeid,
       e.name,
       dh.departmentid
       FROM dh
            LEFT JOIN employees e
                      ON e.departmentid = dh.departmentid;

db<>fiddle

关于带有两个表的 SQL 递归 CTE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52085992/

相关文章:

sql - 在 PostgreSQL 中显示多列的每月总计

mysql - 访问sqlite和mysql的方式有什么区别?

database - 轻量级客户端/服务器数据库?

Java 递归通过 ArrayList 中的引用传递

sql - Oracle使用with子句创建表

java - 使用java从mysql数据库中读取数据

sql - 查看获取复杂条件下的最小日期

python - 如何在 Python sqlite3 中使用元组选择 WHERE IN VALUES?

具有高嵌套级别的 Java 递归

javascript - 为什么 lengthPal 将 testPalindrone.length 存储为数字?