管理层次结构查询

时间:2017-07-31 18:58:51

标签: sql sqlite hierarchical-data recursive-query

尝试创建一个SQL查询,该查询接收员工ID,员工姓名,员工级别,主管ID和主管名称,并返回每个记录的所有相同数据,其中包含来自CEO的给定员工的组织结构

理想情况下,我希望实现:

employee_id, name, employee_level, supervisor_id, supervisor_name, L1_supervisor_id, L1_supervisor_name, L2_supervisor_id, L2_supervisor_name...

我可以使用以下内容从CEO那里获得管理层次结构:

SELECT
lev01.employee_id id_01, lev01.name name_01, lev01.emp_type class_01,
lev02.employee_id id_02, lev02.name name_02, lev02.emp_type class_02,
lev03.employee_id id_03, lev03.name name_03, lev03.emp_type class_03,
lev04.employee_id id_04, lev04.name name_04, lev04.emp_type class_04,
lev05.employee_id id_05, lev05.name name_05, lev05.emp_type class_05,
lev06.employee_id id_06, lev06.name name_06, lev06.emp_type class_06,
lev07.employee_id id_07, lev07.name name_07, lev07.emp_type class_07,
lev08.employee_id id_08, lev08.name name_08, lev08.emp_type class_08,
lev09.employee_id id_09, lev09.name name_09, lev09.emp_type class_09,
lev10.employee_id id_10, lev10.name name_10, lev10.emp_type class_10,
lev11.employee_id id_11, lev11.name name_11, lev11.emp_type class_11,
lev12.employee_id id_12, lev12.name name_12, lev12.emp_type class_12,
lev13.employee_id id_13, lev13.name name_13, lev13.emp_type class_13,
lev14.employee_id id_14, lev14.name name_14, lev14.emp_type class_14,
lev15.employee_id id_15, lev15.name name_15, lev15.emp_type class_15,
lev16.employee_id id_16, lev16.name name_16, lev16.emp_type class_16,
lev17.employee_id id_17, lev17.name name_17, lev17.emp_type class_17,
lev18.employee_id id_18, lev18.name name_18, lev18.emp_type class_18
FROM emp_lst lev01
LEFT OUTER JOIN emp_lst lev02 ON lev01.employee_id = lev02.supervisor_id
LEFT OUTER JOIN emp_lst lev03 ON lev02.employee_id = lev03.supervisor_id
LEFT OUTER JOIN emp_lst lev04 ON lev03.employee_id = lev04.supervisor_id
LEFT OUTER JOIN emp_lst lev05 ON lev04.employee_id = lev05.supervisor_id
LEFT OUTER JOIN emp_lst lev06 ON lev05.employee_id = lev06.supervisor_id
LEFT OUTER JOIN emp_lst lev07 ON lev06.employee_id = lev07.supervisor_id
LEFT OUTER JOIN emp_lst lev08 ON lev07.employee_id = lev08.supervisor_id
LEFT OUTER JOIN emp_lst lev09 ON lev08.employee_id = lev09.supervisor_id
LEFT OUTER JOIN emp_lst lev10 ON lev09.employee_id = lev10.supervisor_id
LEFT OUTER JOIN emp_lst lev11 ON lev10.employee_id = lev11.supervisor_id
LEFT OUTER JOIN emp_lst lev12 ON lev11.employee_id = lev12.supervisor_id
LEFT OUTER JOIN emp_lst lev13 ON lev12.employee_id = lev13.supervisor_id
LEFT OUTER JOIN emp_lst lev14 ON lev13.employee_id = lev14.supervisor_id
LEFT OUTER JOIN emp_lst lev15 ON lev14.employee_id = lev15.supervisor_id
LEFT OUTER JOIN emp_lst lev16 ON lev15.employee_id = lev16.supervisor_id
LEFT OUTER JOIN emp_lst lev17 ON lev16.employee_id = lev17.supervisor_id
LEFT OUTER JOIN emp_lst lev18 ON lev17.employee_id = lev18.supervisor_id
WHERE lev01.supervisor_id IS NULL;

这在两个方面不足:

  1. 查询有点难以阅读和维护。我确信有一种方法可以优化/缩短它,但到目前为止我还没有找到合适的替代方案。

  2. 如果没有原始记录,它将成为将这些记录与原始表格匹配的手动过程。

  3. 任何SQL风格都可以,但我在这里使用SQLite。

1 个答案:

答案 0 :(得分:2)

您需要recursive queries

WITH RECURSIVE org_chart(employee_id, name, emp_type) AS (
  SELECT employee_id, name, emp_type
  FROM emp_lst
  WHERE supervisor_id IS NULL

  UNION ALL

  SELECT employee_id, name, emp_type
  FROM emp_lst e JOIN org_chart o ON e.supervisor_id = o.employee_id 
)
SELECT * FROM org_chart;

请阅读我提供的链接。

SQLite支持自3.8.3版(2014-02-03)以来的递归查询。

几乎所有其他品牌的SQL数据库也支持递归查询语法。见https://www.percona.com/blog/2014/02/11/wither-recursive-queries/

MySQL是最后一个添加支持的人,而且将在下一个版本8.0中出现。