【问题标题】:Self join and recursive selection in a table表中的自连接和递归选择
【发布时间】:2013-08-07 16:46:46
【问题描述】:

假设如下表

| ID |  NAME | ROLE | MGRID |
---------------------------
|  1 |   ONE |    5 |   5 |
|  2 |   TWO |    5 |   5 |
|  3 | THREE |    5 |   6 |
|  4 |  FOUR |    5 |   6 |
|  5 |  FIVE |   15 |   7 |
|  6 |   SIX |   25 |   8 |
|  7 | SEVEN |   25 |   7 |
|  8 | EIGHT |    5 |   8 |

如何获取所有向员工报告的员工的列表,包括处于以下后续报告级别的员工?

我的意思是,给定 emp id 5,我应该得到 [1, 2],给定 7,我应该得到 [1, 2, 5, 7]。我该怎么做?

自我加入在这里会有所帮助吗?现在需要复习我对连接的了解。

【问题讨论】:

  • 这可以使用公用表表达式 (CTE) 来完成,但您的 RDBMS 中可能没有该功能。您使用的是哪个数据库产品和版本?
  • 表在 Oracle 和 MySQL 中
  • 我认为你需要两件事。首先获取向经理报告的员工列表,然后将行转换为列。我与 oracle 脱节,但有一个子句 start with and connect by prior 为您提供了分层视图。
  • @megazoe 。 . .哪个版本的甲骨文? 11g 支持递归 CTE。
  • @GordonLinoff:自 8.0 以来的每个版本都支持使用 connect by 的更简单的语法(顺便说一句:支持递归 CTE 的是 11.2)

标签: mysql sql database oracle join


【解决方案1】:
SELECT id
      FROM emp
START WITH id = 7
CONNECT BY NOCYCLE mgrid = PRIOR id

SQLFIDDLE LINK

【讨论】:

【解决方案2】:

这是使用 Oracle 的 SQL 语句。

select  id, name, role, mgrID
from employees
start with id = 7
connect by NoCycle prior id = mgrid;

请注意,员工 7 的经理是员工 7 - 他们是他们自己的经理。这将导致错误 - “Connect By loop in user data”。通过使用 NoCycle 关键字,您可以告诉 Oracle 检测到这一点并避免错误。

这能解决您的问题吗?

【讨论】:

    【解决方案3】:

    我知道这不是您要问的,但是如果您愿意选择有限数量的级别进行递归,那么写起来还不错。

    SELECT table_2.id
    FROM table LEFT JOIN 
      (table AS table_1 LEFT JOIN table AS table_2 ON table_1.id = table_2.MgrID)
    ON table.id = table_1.MgrID
    WHERE (((table.id)=7));
    

    等。

    【讨论】:

      猜你喜欢
      • 2015-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-28
      • 1970-01-01
      • 2014-08-09
      • 1970-01-01
      相关资源
      最近更新 更多