我使用的是 sql 2012,我有一个具有 3 个级别的自引用表。表结构如下:
表结构
我有另一个表引用这个表,它有 ID 作为外键,所以如果那个表的外键是 6,我需要证明 6 是“AAA”,它是“AA”是“A”的子节点。我需要向下钻取到较低的级别,并且我应该能够从较低的级别上到较高的级别。目前我可以升到二级。
下面是引用另一个表的表的结构。
所以我想报告这两个表,最终输出应该是这样的:
如果我的问题不太清楚,请提问,我会尽力澄清。
最佳答案
假设类别树的深度不超过 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 |
+----+---------+---------+----------+------------+----+--------------+--------------+-------------+
一些额外的列仍然在那里,但我相信你可以去掉它们。请注意,某些类别列具有 null
值。这是因为如果客户属于顶级或中级类别,则没有合理的方法来填写这些列。
关于sql-server - 如何从sql中的自引用表中获取子数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41980851/