Почему мы не можем использовать внешние соединения в рекурсивном CTE?

рассмотрим ниже

;WITH GetParentOfChild AS
    (
        SELECT 
            Rn = ROW_NUMBER() Over(Order By (Select 1))
            ,row_id AS Parents
            ,parent_account_id  As ParentId 
        FROM siebelextract..account
        WHERE row_id = @ChildId
        UNION ALL
        SELECT 
            Rn + 1
            ,a.row_id as Parents
            ,a.parent_account_id As ParentId    
        FROM siebelextract..account a
        JOIN GetParentOfChild gp on a.row_id = gp.ParentId
    )

SELECT TOP 1 @ChildId = Parents 
FROM GetParentOfChild
ORDER BY Rn DESC

что он делает, так это то, что данный любой ребенок, он вернет родителя корневого уровня....Программа отлично работает все время...

просто из любопытства / экспериментального саке я изменил соединение на левое внешнее соединение, и он сообщил

Msg 462, Уровень 16, Состояние 1, Процедура GetParent, Строка 9 Внешнее соединение не допускается в рекурсивной части рекурсивного обобщенного табличного выражения "GetParentOfChild".

мой вопрос в том, почему рекурсивная часть CTE не может принять левое внешнее соединение? Это нарочно?

спасибо

2 ответов


Да, это по дизайну, прочитайте рекомендации по определению и использованию рекурсивных обобщенных табличных выражений

следующие пункты не допускается в CTE_query_definition рекурсивный член:

  • ВЫБЕРИТЕ DISTINCT
  • ГРУППЫ ПО
  • С
  • скаляр агрегации
  • TOP
  • левое, правое, внешнее соединение (внутреннее соединение разрешено)
  • подзапросы

обратите внимание, что если ваш запрос делает левое соединение с ним самостоятельно через CTE, может стать бесконечной рекурсией.


вы не можете использовать левое соединение с рекурсивным CTE, но вы можете использовать внешнее применение, которое должно дать те же результаты.