递归查询以获取子女及其孙子女

时间:2011-07-06 01:52:27

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

我有一个映射表:

Code     Parent_code   Position
--------------------------------
H1       Null          Root
H11      H1            Parent
H111     H11           Parent
H1111    H111          Leaf
H1112    H111          Leaf 

另一个存储叶级代码数量的表

Code   Amount
-------------
H1111  100
H1112  200

即金额仅存储在叶位

我想编写一个查询,通过该查询,叶级别的数据将汇总到其父级并最终汇总到其根目录。

输出如下所示

Code   Amount
-------------
H1     300
H11    300
H111   300
H1111  100
H1112  200

此外,如果我选择H1为root,那么输出应该是它的子孙及其孙子。 如果我选择H11,我应该输出为H111和H111的子项

2 个答案:

答案 0 :(得分:1)

递归公用表表达式应​​该能够为您提供所需的数据。本网站上的一个很好的问题/答案是here

可以帮助您的一个简单示例是:

create table #Code
(
Code varchar(20),
Parent_Code varchar(20)
)
go
insert into #Code (Code, Parent_Code)
select 'H1', null
union
select 'H11', 'H1'
union
select 'H111', 'H11'
union
select 'H1111', 'H111'
union
select 'H1112', 'H111'
union
select 'H12', 'H1'
union
select 'H121', 'H12'
go
create table #CodeAmount
(
Code varchar(20),
Amount decimal
)
go
insert into #CodeAmount (Code, Amount)
select 'H1111', 100
union
select 'H1112', 200
union
select 'H121', 50

go

with CodeAmountRollup(Code, Parent_Code, Amount)
as
(
    select c.Code, c.Parent_Code, ISNULL(ca.Amount, 0) as Amount from #Code c inner join #CodeAmount ca on c.Code = ca.Code
    union all
    select c.Code, c.Parent_Code, Amount as Amount from #Code c inner join CodeAmountRollup car on c.Code = car.Parent_Code     
)
--select * from CodeAmountRollup
select Code, sum(Amount) as Amount from CodeAmountRollup group by Code

答案 1 :(得分:0)

以下是我最近针对类似场景编写的一些SQL的示例,其中我需要返回所有被许可方并按被许可方级别进行排序。希望这可以解释这个概念。

WITH LicenseeEntity (iLicenseeId, vcLicenseeName, vcTradingName,iLicenseeType,iLicenseeStatus, iOwnerLicenseeId, Level)
    AS
    (
        -- Anchor Licensee definition
        SELECT l.iLicenseeId, l.vcLicenseeName, 
               l.vcTradingName,l.iLicenseeType,l.iLicenseeStatus, 
               l.iOwnerLicenseeId, 1 AS Level
        FROM Licensee (nolock) AS l
        WHERE iOwnerLicenseeId IS NULL

        UNION ALL
        SELECT l.iLicenseeId, l.vcLicenseeName, 
               l.vcTradingName,l.iLicenseeType,l.iLicenseeStatus, 
               l.iOwnerLicenseeId, 1 AS Level + 1
        FROM Licensee (nolock) AS l
        INNER JOIN LicenseeEntity AS le ON l.iOwnerLicenseeId = le.iLicenseeId
    )

    SELECT *  FROM LicenseeEntity le