如何从sql中的自引用表中获取子数据

时间:2017-02-01 13:19:44

标签: sql-server ssrs-2012

我正在使用sql 2012,我有一个自我引用表,有3个级别。表结构如下:

表格结构

我有另一个引用该表的表,它有ID作为外键,所以如果该表的外键是6,我需要显示6是“AAA”,它是“”的子节点“ AA“是”A“的子节点。我需要深入到较低的水平,从较低的水平我应该能够上升到较高的水平。目前我可以上升到第二级。

下面是引用另一个表的表的结构。

所以我想报告这两个表,最终输出应该如下所示:

如果我的问题不太明确,请问我会尝试澄清它。

1 个答案:

答案 0 :(得分:1)

假设类别树的深度不超过3个级别,这应该有效:

declare @Catergory table (
    ID int not null,
    Name nvarchar(10) not null,
    ParentID int null
)
declare @Customer table (
    ID int not null,
    Name nvarchar(10) not null,
    SurName nvarchar(10) not null,
    Address nvarchar(30) not null,
    CategoryId int not null
)
insert into @Catergory (ID, Name, ParentID)
values (1, 'A', null), (2, 'B', null),
    (3, 'C', null), (4, 'AA', 1),
    (5, 'CC', 3), (6, 'AAA', 4),
    (7, 'BB', 2), (8, 'AAA', 4),
    (9, 'CCC', 5), (10, 'AA', 1)

insert into @Customer (ID, Name, SurName, Address, CategoryId)
values (1, 'Duck', 'Duffy', '10 Steet', 10),
 (2, 'Ben', 'Ten', '10 Steet', 6),
 (3, 'Cat', 'Dog', '10 Steet', 5),
 (4, 'Chicken', 'Wings', '10 Steet', 1),
 (5, 'Fish', 'Water', '10 Steet', 7)

-- build structure using assumption that the depth is max three levels

select *
from @Customer cust
    join (
        select ID, Name as CategoryName, null As CategoryType, null as SubCategory from @Catergory roots where ParentID is null
        union
        select mids.ID, roots.Name, mids.Name, null from @Catergory mids
            join @Catergory roots on mids.ParentID = roots.ID and roots.ParentID is null
        union
        select leafs.ID, roots.Name, mids.Name, leafs.Name from @Catergory leafs
            join @Catergory mids on leafs.ParentID = mids.ID 
            join @Catergory roots on mids.ParentID = roots.ID and roots.ParentID is null
    ) as struct on cust.CategoryId = struct.ID
order by cust.id

输出:

+----+---------+---------+----------+------------+----+--------------+--------------+-------------+
| ID |  Name   | SurName | Address  | CategoryId | ID | CategoryName | CategoryType | SubCategory |
+----+---------+---------+----------+------------+----+--------------+--------------+-------------+
|  1 | Duck    | Duffy   | 10 Steet |         10 | 10 | A            | AA           | NULL        |
|  2 | Ben     | Ten     | 10 Steet |          6 |  6 | A            | AA           | AAA         |
|  3 | Cat     | Dog     | 10 Steet |          5 |  5 | C            | CC           | NULL        |
|  4 | Chicken | Wings   | 10 Steet |          1 |  1 | A            | NULL         | NULL        |
|  5 | Fish    | Water   | 10 Steet |          7 |  7 | B            | BB           | NULL        |
+----+---------+---------+----------+------------+----+--------------+--------------+-------------+

还有一些额外的列,但我相信你可以摆脱它们。请注意,某些cartegory列的值为null。这是因为如果客户处于顶级或中级类别,则没有合理的方法来填写这些列。