CONNECT BY или иерархические запросы в СУБД, отличных от Oracle
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
псевдо колонка и отступ, достигнутый с ее помощью, не так важен для меня
3 ответа
На сайте разработчиков developerWorks есть статья Port CONNECT BY to DB2, в которой описана хорошая конверсия. Также интересная статья в Explain Extended (блог Quassnoi), в которой показано некоторое различие между CONNECT BY и рекурсивным CTE: список смежности и вложенные множества: Oracle, основанный на строках и множествах. У него также есть хорошая статья на тему "SQL Server: действительно ли рекурсивный CTE основан на множествах?". Кажется, что "рекурсивный CTE в Oracle также не основан на множестве". Я надеюсь, что это поможет с преобразованием, рекурсией в JOOQ и пониманием различия обеих реализаций рекурсии в SQL.
С уважением, JJ.
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;
Обход SO показал следующие вопросы и ответы, которые касаются иерархических запросов в различных базах данных. Последний из них относится к ресурсу MySql, который предоставляет общий подход SQL.
Построение таблицы зависимостей с помощью рекурсивного запроса
Генерация дерева на основе глубины из иерархических данных в MySQL (без CTE)