8

Oracle 附带了一个非常方便的特性。您可以使用以下子句创建分层查询(递归行为):

CONNECT BY [NOCYCLE] {condition [AND condition...]} [START WITH condition]

如此处所述:

http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/queries003.htm

我想知道,是否有任何其他已建立的 RDBMS 支持等效或类似的语法?或者可以使用常规 SQL 来一般地模拟这样的递归行为吗?

我希望能够模拟的一个很好的例子是这个(取自 Oracle 文档):

    SELECT LPAD(' ', 2 * (LEVEL-1)) || last_name org_chart, 
           employee_id, manager_id, job_id
      FROM employees
START WITH job_id = 'AD_VP' 
CONNECT BY PRIOR employee_id = manager_id; 

导致:

ORG_CHART          EMPLOYEE_ID MANAGER_ID JOB_ID
------------------ ----------- ---------- ----------
Kochhar                    101        100 AD_VP
  Greenberg                108        101 FI_MGR
    Faviet                 109        108 FI_ACCOUNT
    Chen                   110        108 FI_ACCOUNT
    Sciarra                111        108 FI_ACCOUNT
    Urman                  112        108 FI_ACCOUNT
    Popp                   113        108 FI_ACCOUNT
  Whalen                   200        101 AD_ASST
  Mavris                   203        101 HR_REP
  Baer                     204        101 PR_REP
  Higgins                  205        101 AC_MGR
    Gietz                  206        205 AC_ACCOUNT
De Haan                    102        100 AD_VP
  Hunold                   103        102 IT_PROG
    Ernst                  104        103 IT_PROG
    Austin                 105        103 IT_PROG
    Pataballa              106        103 IT_PROG
    Lorentz                107        103 IT_PROG

伪列和用它实现的LEVEL缩进对我来说并不重要

4

3 回答 3

5

SQL Server 使用公用表表达式(WITH 语句)来实现相同的目的(请参阅使用公用表表达式的递归查询)。

这种查询也可以在Oracle中使用(如果我没记错的话,从11g开始)。

生成的查询更复杂:

WITH emp(employee_id, manager_id, job_id, last_name, lvl)
AS (
    SELECT e.employee_id, e.manager_id, e.job_id, e.last_name, 1 lvl
    FROM employees e
    WHERE job_id = 'AD_VP'
    UNION ALL
    SELECT e.employee_id, e.manager_id, e.job_id, e.last_name, r.lvl + 1 lvl
    FROM employees e
    JOIN emp r ON r.employee_id = e.manager_id
)
SELECT LPAD(' ', 2 * (lvl-1)) || last_name org_chart,
    employee_id, manager_id, job_id
FROM emp;
于 2011-06-19T08:17:28.873 回答
4

developerworks 站点Port CONNECT BY to DB2上有一篇文章进行了很好的转换。还有一篇关于 Explain Extended(Quassnoi 的博客)的有趣文章,显示了 CONNECT BY 和递归 CTE 之间的一些区别:邻接列表与嵌套集:Oracle,基于行和基于集合。他还有一篇关于“SQL Server: are the recursive CTE's really set-based?”的好文章。似乎“Oracle 中的递归 CTE 也不是基于集合的”。我希望这有助于 JOOQ 中的转换、递归以及理解 SQL 中递归的两种实现的区别。

问候,JJ。

于 2012-03-04T00:51:26.410 回答
2

对 SO 的拖网显示了以下问题和答案,这些问题和答案处理了对各种数据库的分层查询。最后一个引用了一个MySql 资源,它提供了一个通用的 SQL 方法。

使用递归查询构建表依赖图

SQL中的递归选择

SQL递归查询

从 MySQL 中的分层数据生成基于深度的树(无 CTE)

于 2011-06-19T08:54:41.413 回答