英语不是我的第一语言,所以我会尝试尽可能清楚地解释我所寻找的内容。我尝试了很多个小时,但我无法找到我需要的东西。
我有以下表结构,它是一个简单的父/子层次结构。我将只有2个级别(例如:没有孩子的记录,有孩子的记录和那些没有孩子的孩子):
表格结构:
[Id] [int] IDENTITY(1,1) NOT NULL,
[Description] [nvarchar](255) NULL,
[ParentId] [int] NULL,
以下是表格中的数据:
Id Description ParentId
----------- ----------------- -----------
1 aaaa NULL
2 bbbb NULL
3 cccc NULL
4 dddd NULL
5 eeee NULL
6 ffff NULL
7 gggg NULL
8 aaaa-2 1
9 aaaa-3 1
10 bbbb-2 2
11 bbbb-3 2
表格中的数据:
我想查询返回没有孩子的所有记录,以及父母孩子的最后一次出现而没有返回相应的父母。请参阅下一个图像以获得预期结果(我希望查询仅返回以颜色标记的记录):
预期结果:
Id Description ParentId
----------- ----------------- -----------
3 cccc NULL
4 dddd NULL
5 eeee NULL
6 ffff NULL
7 gggg NULL
9 aaaa-3 1
11 bbbb-3 2
我尝试过类似的事情:
WITH CTE ([Id], [Description], [ParentId], LEVEL) AS
( SELECT [Id], [Description], [ParentId], 1 LEVEL
FROM [Test].[dbo].[Avis]`enter code here`
WHERE [ParentId] IS NULL AND [Id] NOT IN ??
UNION ALL
SELECT E.[Id], E.[Description], E.[ParentId], CTE.LEVEL + 1
FROM [Test].[dbo].[Avis] E
INNER JOIN CTE CTE ON E.[ParentId] = CTE.[Id]
WHERE E.[ParentId] IS NOT NULL
)
SELECT *
FROM CTE
答案 0 :(得分:1)
您有两个要求:
基本上,你正试图在每个关系中获得最后一片叶子。
要获取不在关系中的所有行,请获取那些具有空父ID且其id不用作另一行的父ID的行。
要获取最后一个子节点,请使用子查询获取每个父ID的最大ID,并使用这些ID选择所需的行。
您可以将这两个需求拆分为两个带有union的查询,但由于父请求不会对叶子造成伤害,因此您只需将null父ID拆分或使用或者具有max id要求即可。
SELECT *
FROM @Avis a
WHERE a.Id NOT IN (SELECT ParentId FROM @Avis WHERE ParentId IS NOT NULL)
AND (
a.ParentId IS NULL
OR a.Id IN (SELECT MAX(Id) FROM @Avis WHERE ParentId IS NOT NULL GROUP BY ParentId)
)
<强>结果
Id Description ParentId
----------- ------------ -----------
3 cccc NULL
4 dddd NULL
5 eeee NULL
6 ffff NULL
7 gggg NULL
9 aaaa-3 1
11 bbbb-3 2
奖励:即使关系是多层深度,此查询也会获得每个父级的最后一个叶子。