【问题标题】:Can a Recursive CTE be used for hierarchical rows with accumulating trickle down sub-joins?递归 CTE 可以用于具有累积涓滴子连接的分层行吗?
【发布时间】:2021-02-20 18:49:06
【问题描述】:

我在使用 ID 和父级的表中为“组”使用递归 CTE。

第一个表“组”(Project_Estimate_Group) 是具有 ID 和父级的层次结构。第二个表“GroupOptions”(Project_Estimate_Group_Option)适应组和选项之间的多对多关系。如果您将选项添加到任何级别,它会向下渗透到该分支中的任何子级。

我需要将 Groups 的父级和递归子级加入到 GroupOptions 中,并让这些联接在每个递归级别中“涓涓细流”,以便在每个级别您都可以加入当前选项以及加入选项分支中的每个父级。

我需要为没有 OptionID 的每个组设置一行,为每个加入的 OptionID 设置一行。有些关卡没有选项。

这可以通过递归 CTE 来完成吗?

Table1“组”有

Parent   ID
-------- ------
NULL     1
1        2
2        3
NULL     4
4        5

Table2“GroupOptions”有

GroupID  OptionID
-------- --------
1        10
1        11
2        12
5        20

加入后我需要

Parent   ID       OptionID
-------- -------- ----------
NULL     1        0
NULL     1        10
NULL     1        11
1        2        0
1        2        10
1        2        11
1        2        12
2        3        0
2        3        10
2        3        11
2        3        12
NULL     4        0
4        5        0
4        5        20

以下查询将关闭,但只会返回当前组及其父级的选项,而不是其祖父级或更高级别的选项

DECLARE @EstimateID int = (SELECT MAX(ID) FROM dbo.Project_Estimate);
WITH egroup (EstimateID, ParentID, GroupID, OptionID) AS
(
SELECT @EstimateID, NULL, peg.ID, 0
FROM dbo.Project_Estimate_Group peg
WHERE peg.Estimate = @EstimateID AND peg.Parent IS NULL
UNION ALL
SELECT @EstimateID, NULL, peg.ID, pego.OptionID
FROM dbo.Project_Estimate_Group peg
JOIN dbo.Project_Estimate_Group_Option pego on peg.ID = pego.GroupID
WHERE peg.Estimate = @EstimateID AND peg.Parent IS NULL
UNION ALL
SELECT @EstimateID, peg.Parent, peg.ID, 0
FROM dbo.Project_Estimate_Group peg
  JOIN egroup on peg.Parent = egroup.GroupID
UNION ALL
SELECT @EstimateID, peg.Parent, peg.ID, pego.OptionID
FROM dbo.Project_Estimate_Group peg
  JOIN egroup on peg.Parent = egroup.GroupID
  JOIN dbo.Project_Estimate_Group_Option pego on peg.ID = pego.GroupID
UNION ALL
SELECT @EstimateID, peg.Parent, peg.ID, pego.OptionID
FROM dbo.Project_Estimate_Group peg
  JOIN egroup on peg.Parent = egroup.GroupID
  JOIN dbo.Project_Estimate_Group_Option pego on peg.Parent = pego.GroupID
)

SELECT DISTINCT EstimateID, ParentID, GroupID, OptionID 
FROM egroup
JOIN dbo.Project_Estimate e on egroup.EstimateID = e.ID

【问题讨论】:

    标签: sql-server tsql


    【解决方案1】:

    试试这个:

    ;WITH CTE AS 
    (   
        -- Get all Groups - GroupOptions combinations
        SELECT g.Parent, g.ID, go.OptionID
        FROM Groups g
        INNER JOIN GroupOptions go ON g.ID = go.GroupID  
    
        UNION ALL
    
        -- Go down one level passing option value
        SELECT g.Parent, g.ID, c.OptionID
        FROM CTE c
        INNER JOIN Groups g ON c.ID = g.Parent
    )
    SELECT *
    FROM CTE
    
    UNION ALL
    
    -- Union each group row without the OptionID
    SELECT Parent, ID, 0
    FROM Groups
    ORDER BY ID, OptionID
    

    Demo here

    【讨论】:

    • 来自Transact-SQL Syntax Conventions: "; Transact-SQL 语句终止符。尽管在此版本的 SQL Server 中大多数语句不需要分号,但在未来版本中将需要它。"养成使用它的习惯。
    猜你喜欢
    • 2013-02-06
    • 2014-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-25
    • 2019-02-17
    • 2016-03-15
    相关资源
    最近更新 更多