【问题标题】:How to query all parent with no child, and last existing child of a parent when only 2 levels?如何在只有 2 个级别时查询所有没有孩子的父母,以及父母的最后一个现有孩子?
【发布时间】:2018-04-17 13:06:01
【问题描述】:

英语不是我的第一语言,所以我会尽量清楚地解释我在寻找什么。我尝试了很多小时的搜索,但找不到我真正需要的东西。

我有以下表结构,这是一个简单的父/子层次结构。我将永远只有 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

【问题讨论】:

  • 这里的大多数人想要格式化文本,而不是图像(或图像链接)。
  • 你试过什么?向我们展示您当前的查询尝试。
  • 抱歉包含的图像,我无法直接包含它们,因为我没有足够的堆栈溢出点。
  • 格式化文本没有信誉要求!
  • 为什么不发布表格和代码的图片? meta.stackoverflow.com/questions/285551/…

标签: sql sql-server


【解决方案1】:

你有两个要求:

  1. 获取所有不存在关系的行
  2. 获取每个父母的最后一个孩子

本质上,您是在尝试获得每段关系的最后一片叶子。

要获取所有不存在关系的行,请获取父 ID 为空且其 ID 未用作另一行的父 ID 的行。

要获取最后一个孩子,请使用子查询获取每个父 ID 的最大 ID,并使用这些 ID 选择您需要的行。

您可以使用联合将这两个需求拆分为两个查询,但由于非父需求不会伤害叶子,您可以只拆分空父 id 或使用 or 具有最大 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

奖励:此查询将获取每个父级的最后一个叶子,即使关系是多个级别的深度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-07
    • 2011-10-20
    相关资源
    最近更新 更多