简体   繁体   中英

How to put a CTE as a subquery

In SQL Server, I have a CTE and a select statement.

The CTE looks like

WITH Recursion AS (
    SELECT Value, GroupID, Type
    FROM @GroupMembership
    WHERE GroupID = @requestingGroupID
    UNION ALL
    SELECT M.Value, M.GroupID, M.Type
    FROM Recursion AS R
    INNER JOIN @GroupMembership AS M ON R.Value = M.GroupID AND R.Type = 'Group'
)
SELECT * FROM Recursion

and the select statement is this

select * 
from [Right] r
inner join Group on r.groupid = Group.id 
inner join (
  -- CTE but @requestingGroupID should be Group.id
) C on C.GroupID = Group.id

I want to nest the CTE inside the brackets, but the @requestingGroupID from the CTE should be referencing Group.id from outside the bracket.

When I try to do this, I get syntax errors. Does anyone know how to do it?

Thanks

Without sample data and expected results, it's hard to give a definitive answer.

But basically, you cannot use a recursive CTE as an APPLY (where you push outer references in).

The only way to do this is to put the recursive part into an inline Table Valued Function, then APPLY it to the rest of the query

CREATE OR ALTER FUNCTION GetDescendants (@requestingGroupID int)
RETURNS TABLE AS RETURN
WITH Recursion AS (
    SELECT Value, GroupID, Type
    FROM GroupMembership
    WHERE GroupID = @requestingGroupID
    
    UNION ALL
    
    SELECT M.Value, M.GroupID, M.Type
    FROM Recursion AS R
    INNER JOIN GroupMembership AS M ON R.Value = M.GroupID AND R.Type = 'Group'
)
SELECT *
FROM Recursion;
select * 
from [Right] r
inner join Group g on r.groupid = g.id 
CROSS APPLY dbo.GetDescendant ( g.id) C

db<>fiddle

Alternatively, you can re-arrange your query so that the main SELECT is in the anchor part (first part) of the recursion. Admittedly this is not always possible.

WITH Recursion AS (
    SELECT r.Id, Value, GroupID, Type
    FROM [Right] r
    inner join Group g on r.groupid = g.id 
    JOIN @GroupMembership gm ON gm.GroupID = g.GroupID
    
    UNION ALL
    
    SELECT R.Id, M.Value, M.GroupID, M.Type
    FROM Recursion AS R
    INNER JOIN @GroupMembership AS M ON R.Value = M.GroupID AND R.Type = 'Group'
)
SELECT *
FROM Recursion

db<>fiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM