【问题标题】:Aggregate Self-Referencing Table聚合自引用表
【发布时间】:2013-10-04 07:10:37
【问题描述】:

我已经看到了几个关于如何递归查询自引用表的问题/答案,但我正在努力将我发现的答案应用到每个父母、祖父母等,无论项目在哪里位于层次结构中。

MyTable
-----------
Id
Amount
ParentId

数据:

Id    Amount      Parent Id
 1      100          NULL
 2      50            1
 3      50            1
 4      25            2
 5      10            4

如果我在不过滤和求和的情况下运行此查询,结果将是:

Id   SumAmount
 1       235
 2        85
 3        50
 4        35
 5        10

换句话说,我想查看 MyTable 中的每个项目以及所有子项的总金额。

【问题讨论】:

    标签: sql sql-server sql-server-2008 recursion


    【解决方案1】:

    类似的东西?

        WITH temp (ID, ParentID, TotalAmount)
    AS
    (
        SELECT ID, ParentID, Amount
        FROM MyTable
        WHERE NOT EXISTS (SELECT * FROM MyTable cc WHERE cc.ParentID = MyTable.ID)
    
        UNION ALL
    
        SELECT MyTable.ID, MyTable.ParentID, TotalAmount + MyTable.Amount
        FROM MyTable
        INNER JOIN temp ON MyTable.ID = temp.ParentID
    )
    
    SELECT ID, SUM(TotalAmount) FROM
        (SELECT ID, TotalAmount - (SELECT Amount FROM MyTable M WHERE M.ID = temp.ID) TotalAmount
         FROM temp
         UNION ALL
         SELECT ID, Amount AS TotalAmount FROM MyTable) X
    GROUP BY ID
    

    根据下面的 cmets 编辑了查询,现在一切正常。

    【讨论】:

    • 我认为TotalAmount + MyTable.Amount 是错误的,因为它的总和低于SUM(TotalAmount),但这是进行递归的好方法。 +1 顺便说一句,应该是 MyTable.Amount 而已
    • 这就像你从根到叶有多个分支的情况。当第一个查询从叶子到根时,您可能会为同一个父级返回多个记录(每个分支一个)。
    • 不,你的权利。我以为他们会追求不同的结果。我重新审视了这个问题,我认为他们确实想要你拥有的方式。
    • @RomanPekar 你说的很对!谢谢!更改了查询,但不可否认,您的解决方案更优雅,应该被接受。
    【解决方案2】:
    with cte as (
        select t.Id, t.Amount, t.Id as [Parent Id]
        from Table1 as t
    
        union all
    
        select c.Id, t.Amount, t.Id as [Parent Id]
        from cte as c
            inner join Table1 as t on t.[Parent Id] = c.[Parent Id]
    )
    
    select Id, sum(Amount) as Amount
    from cte
    group by Id
    

    sql fiddle demo

    【讨论】:

      猜你喜欢
      • 2018-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-12
      • 2023-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多