【问题标题】:Oracle join with recursiveOracle加入递归
【发布时间】:2021-02-23 04:22:18
【问题描述】:

我有一个员工表和部门表。

如果 dep_id 的状态列具有“A”,我想编写一个列出employee_ids 的查询。

例如:

对于employee_id = 1,我应该看到1,因为它的父dept_id(10) 的状态='A'

对于employee_id = 2,我应该看到2,因为它的父dept_id(200) 的状态='A'

对于employee_id = 5,我不应该是5,因为它的父母没有status = 'A'

Department Table

employee_id | dept_id     | status |level
1           |10           | null   | 1
2           |20           | null   | 1
10          |100          | A      | 2
20          |200          | null   | 2
100         |1000         | null   | 3
200         |2000         | A      | 3
450         |750          | null   | 1
5           |30           | null   | 1
30          |300          | null   | 2
3           |400          | A      | 1
400         |4000         | null   | 2

Employee Table

employee_id | employee_name
1           |  steven
2           |  jone
3           |  eric
4           |  mark
5           |  harry

上面两个表的示例结果是:

  | employee_id|
      1
      2

我的查询现在是这样的:

  SELECT Employee.employee_id FROM Department
  JOIN Employee ON Employee.employee_id = Department.employee_id;

【问题讨论】:

  • AFAIK 这是一个简单的附加 WHERE Department.status = 'A'
  • 它也给出 3,但其父部门不包含“A”。标准是父部门应包含“A”。查询应检查父部门
  • 啊抱歉,没有像 @Tejash 那样实现对 dept_id = employee_id 的递归连接

标签: sql oracle recursion join


【解决方案1】:

您需要按如下方式查询层次结构:

SQL> -- SAMPLE DATA
SQL> WITH DEPT_EMP (employee_id , dept_id, status, lVL) as
  2  (select 1   , 10  ,  null, 1 from dual union all
  3  select 2   , 20  ,  null, 1 from dual union all
  4  select 10  , 100 ,  'A'   , 2 from dual union all
  5  select 20  , 200 ,  null, 2 from dual union all
  6  select 100 , 1000,  null, 3 from dual union all
  7  select 200 , 2000, 'A'   , 3 from dual union all
  8  select 450 , 750 ,  null, 1 from dual union all
  9  select 5   , 30  ,  null, 1 from dual union all
 10  select 30  , 300 ,  null, 2 from dual union all
 11  select 3   , 400 ,  'A'   , 1 from dual union all
 12  select 400 , 4000,  null, 2 from dual),
 13  EMPS (employee_id, employee_name) AS
 14  (SELECT 1, 'steven' FROM DUAL UNION ALL
 15  SELECT 2, 'jone'   FROM DUAL UNION ALL
 16  SELECT 3, 'eric'   FROM DUAL UNION ALL
 17  SELECT 4, 'mark'   FROM DUAL UNION ALL
 18  SELECT 5, 'harry'  FROM DUAL)
 19  -- YOUR QUERY STARTS FROM HERE
 20  SELECT D.EMPLOYEE_ID, E.EMPLOYEE_NAME
 21    FROM (SELECT STATUS, LVL, CONNECT_BY_ROOT EMPLOYEE_ID AS EMPLOYEE_ID
 22    FROM DEPT_EMP
 23  CONNECT BY  EMPLOYEE_id = PRIOR dept_id) D
 24    JOIN EMPS E ON D.EMPLOYEE_ID = E.EMPLOYEE_ID
 25   WHERE STATUS = 'A' AND LVL > 1;

EMPLOYEE_ID EMPLOY
----------- ------
          1 steven
          2 jone

SQL>

【讨论】:

  • 嗨@tom,你能解释一下这是一个很好的答案吗?当我删除条件:AND LVL > 1 时,查询返回 3 个结果。在您的问题中没有提到 level 列并且它应该大于 1 ? Tejash - 你也有同样的问题。这是小提琴,您可以在其中看到它返回 3 行:dbfiddle.uk/… 我的答案返回 2 行。谢谢。干杯。
【解决方案2】:
SELECT E.employee_id, E.EMPLOYEE_NAME
FROM Employee E
JOIN department D ON E.employee_id = D.employee_id
join department T on D.dept_id = T.employee_id
where T.status = 'A'

这是一个演示:

DEMO

【讨论】:

    猜你喜欢
    • 2014-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-27
    • 2013-03-01
    • 2016-02-12
    相关资源
    最近更新 更多