Обнаружение цикла с рекурсивным факторингом подзапроса

Взгляните к подсказке, выделенной к вставке/обновлению метки времени на vim.wikia.

22
задан Rob van Wijk 16 November 2009 в 09:39
поделиться

4 ответа

В документации по CYCLE упоминается «ряд предков». Однако, вообще говоря, в рекурсивном CTE нет понятия «родительский ряд». Это операция, основанная на множестве, которая может давать результаты полностью вне дерева. Вообще говоря, часть привязки и рекурсивная часть могут даже использовать разные таблицы.

Поскольку рекурсивные CTE обычно используются для построения деревьев иерархии, Oracle решил добавить проверку цикла. Но из-за основанного на множестве способа работы рекурсивного CTE , обычно невозможно сказать, будет ли следующий шаг генерировать цикл или нет, потому что без четкого определения условия цикла "родительская строка" невозможно

Чтобы выполнить «следующий» шаг, Однако у него нет никаких средств для обнаружения циклов, потому что циклы изначально не определены.

Как упоминалось ранее, MySQL не реализует CTE на все (он не реализует HASH JOIN или MERGE JOIN , а только вложенные циклы, так что не сильно удивляйтесь).

Как ни странно, я получил письмо сегодня по этой теме, о котором я расскажу в своем блоге.

Обновление:

Рекурсивные CTE в SQL Server не более чем СВЯЗАТЬСЯ С замаскированным. См. Шокирующие подробности в этой статье в моем блоге:

14
ответ дан 29 November 2019 в 05:33
поделиться

MySQL Server версии 5.0.45 не понравилось с :

ОШИБКА 1064 (42000): у вас есть ошибка в синтаксисе SQL; проверить руководство, соответствующее вашей версии сервера MySQL, для правильного синтаксис для использования рядом с 'с tr (id, parent_id) as (select id, parent_id из t, где id = 1, объединить все s 'в строке 1.

1
ответ дан 29 November 2019 в 05:33
поделиться

PostgreSQL supports WITH-style hierarchical queries, but doesn't have any automatic cycle detection. This means that you need to write your own and the number of rows returned depends on the way you specify join conditions in the recursive part of the query.

Both examples use an array if IDs (called all_ids) to detect loops:

WITH recursive tr (id, parent_id, all_ids, cycle) AS (
    SELECT id, parent_id, ARRAY[id], false
    FROM t
    WHERE id = 1
    UNION ALL
    SELECT t.id, t.parent_id, all_ids || t.id, t.id = ANY(all_ids)
    FROM t
    JOIN tr ON t.parent_id = tr.id AND NOT cycle)
SELECT id, parent_id, cycle
FROM tr;

 id | parent_id | cycle
----+-----------+-------
  1 |         2 | f
  2 |         1 | f
  1 |         2 | t


WITH recursive tr (id, parent_id, all_ids, cycle) AS (
    SELECT id, parent_id, ARRAY[id], false
    FROM t
    WHERE id = 1
    UNION ALL
    SELECT t.id, t.parent_id, all_ids || t.id, (EXISTS(SELECT 1 FROM t AS x WHERE x.id = t.parent_id))
    FROM t
    JOIN tr ON t.parent_id = tr.id
    WHERE NOT t.id = ANY(all_ids))
SELECT id, parent_id, cycle
FROM tr;

 id | parent_id | cycle
----+-----------+-------
  1 |         2 | f
  2 |         1 | t
6
ответ дан 29 November 2019 в 05:33
поделиться

AFAIK:

  • MySQL не поддерживает рекурсивные CTE
  • SQL-сервер не поддерживает цикл обнаружение в рекурсивных CTE
3
ответ дан 29 November 2019 в 05:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: