递归 CTE 查找所有项目的所有祖先

2024-01-09

我有一个简单的层次结构,需要能够生成一个表,将表中的每个项目与其所有祖先相匹配。 (大写强调这不是一个重复的问题!)

所以这是一个表:

Select Item='A', Parent=null into Items union
Select Item='B', Parent='A'  union
Select Item='C', Parent='A'  union
Select Item='D', Parent='B'  union
Select Item='E', Parent='B'  union
Select Item='F', Parent='C'  union
Select Item='G', Parent='C'  union
Select Item='H', Parent='D'  
Go

...代表这个层次结构:

       A
     /   \
    B     C
   / \   / \
   D E   F G
  /
  H

所以B有一个祖先(A),H有3个祖先(D,B,A)。这是所需的输出:

 Item | Ancestor
 B    | A
 C    | A
 D    | A
 D    | B
 E    | A
 E    | B
 F    | A
 F    | C
 G    | A
 G    | C
 H    | A
 H    | B
 H    | D

使用递归 CTE,我能够找到任何一项的所有后代......

Create Function ItemDescendants(@Item char) Returns @result Table(Item char) As Begin
    ; With AllDescendants as (
        Select
            Item,
            Parent
        From Items i
        Where Item=@Item
        UNION ALL
        Select
            i.Item,
            i.Parent
        from Items i
        Join AllDescendants a on i.Parent=a.Item
    )
    Insert into @result (Item)
    Select Item from AllDescendants
    Where Item<>@Item;
    Return;
End
Go

...但是为了获得完整的扩展列表,我必须求助于光标(哎呀!):

Select Item, Parent into #t From Items

Declare @Item char
Declare c Cursor for (Select Item from Items)
Open c
Fetch c into @Item
While (@@Fetch_Status=0) Begin
    Insert into #t (Item, Ancestor) Select Item, @Item from dbo.ItemDescendants(@Item) 
    Fetch c into @Item
End
Close c
Deallocate c

Select Distinct
    Item,
    Ancestor
From #t
Where Parent is not null
Order by Item,Parent

Drop Table #t

这是可行的,但如果我能用一个优雅的查询来完成它,我会更高兴。看起来应该是可能的 - 有什么想法吗?


假设我理解正确,它应该像从叶节点向后递归一样简单(这很容易,因为表 Items 仅存储叶节点):

;with AncestryTree as (
  select Item, Parent
  from Items
  where Parent is not null
  union all
  select Items.Item, t.Parent  
  from AncestryTree t 
  join Items on t.Item = Items.Parent
 )
select * from AncestryTree
order by Item, Parent

SQL Fiddle 演示 http://sqlfiddle.com/#!6/693fc/9

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

递归 CTE 查找所有项目的所有祖先 的相关文章

  • 不是 select 中带有 MAX 的单组组函数

    Select sg gameno Max sg Year sg end sg hostcity country olympic name from Summergames s Country co where s country isoco
  • MySQL 中的 UDF 性能

    我注意到 当查询在 SELECT 或 WHERE 子句中调用 UDF 时 MySQL 查询执行时间的性能会呈指数级下降 有问题的 UDF 查询本地表以返回标量值 因此它们不仅执行算术表达式 而且充当相关子查询 我通过简单地删除 UDF 并使
  • 更新每组单行

    的背景 我有一个临时表 其中包含唯一的 rowID OrderNumber 和 guestCount 等信息 RowID 和 OrderNumber 已存在于该表中 并且我正在运行一个新查询来填充每个 orderNumber 缺少的 gue
  • 按两列的最小值排序

    I use SQL Server 2008 R2 我需要按两列的最小值对表进行排序 该表如下所示 ID integer Date1 datetime Date2 datetime 我希望我的数据按至少两个日期排序 以这种方式对该表进行排序的
  • 动态规划的复杂组合条件

    我正在探索动态规划设计方法如何与问题的底层组合属性相关 为此 我正在查看的规范实例硬币找零问题 Let S d 1 d 2 d m and n gt 0是请求的金额 我们可以用多少种方式相加n仅使用中的元素S 如果我们遵循一个动态规划如果要
  • 如何在postgres中获取数组大小大于1的数组

    我有一个看起来像这样的表 val fkey num 1 1 1 1 2 1 1 3 1 2 3 1 我想要做的是返回一组行 其中值按 val 分组 并带有一个 fkey 数组 但仅限于 fkey 数组大于 1 的情况 因此 在上面的示例中
  • 仅基于月份和年份的 SQL Server 日期比较

    我无法确定仅根据月份和年份比较 SQL 中的日期的最佳方法 我们根据日期进行计算 由于计费是按月进行的 因此该月的日期会造成更多障碍 例如 DECLARE date1 DATETIME CAST 6 15 2014 AS DATETIME
  • 将 5 gig 文件导入表时出错

    我正在尝试批量插入表 use SalesDWH go BULK INSERT dbo npi FROM S tmp npi csv WITH FIELDTERMINATOR ROWTERMINATOR n lastrow 200 first
  • 如何使用 SQL - INSERT...ON DUPLICATE KEY UPDATE?

    我有一个脚本可以捕获推文并将其放入数据库中 我将在 cronjob 上运行脚本 然后在我的网站上显示数据库中的推文 以防止达到 Twitter API 的限制 所以我不想在我的数据库中有重复的推文 我知道我可以使用 INSERT ON DU
  • HANA 列表/显示表 SQL 命令

    如何通过 SQL 显示 列出 SAP HANA 中的所有表 SAP HANA 通过系统表提供数据库目录 就像大多数其他 DBMS 一样 TABLES https help sap com saphelp hanaplatform helpd
  • SQL Server 2008 中的 FREETEXT 查询不进行短语匹配

    我在 SQL Server 2008 中有一个全文索引表 我正在尝试使用 FULLTEXT 查询精确的短语匹配 我不认为使用 CONTAINS 或 LIKE 适合于此 因为在其他情况下查询可能不准确 用户没有用双引号括起短语 并且一般来说我
  • 递归与迭代算法

    我正在实现欧几里德算法来查找两个整数的 GCD 最大公约数 给出了两个示例实现 递归和迭代 http en wikipedia org wiki Euclidean algorithm Implementations http en wik
  • MySQL如何在没有过程/函数的情况下执行命令块

    我尝试在 MySQL Workbench 上运行一段 SQL 命令 就像在 SQL Server 上一样 但它告诉我 声明在此位置无效 我在网上看到了各种这样的例子 我真的不明白为什么会出现这个错误 一些提示 代码 其中 SQL Serve
  • T-SQL 问题:查询 XML

    任何人都可以告诉我如何从这些数据生成 DATA Key ParentKey 5 NULL 25 5 33 25 26 5 27 5 34 27 28 5 29 5 这个 XML 结果 RESULTS
  • 嵌入定义绑定变量的 Oracle PL/SQL 代码的 Shell 脚本

    如果我运行下面的脚本 我会收到错误SP2 0552 未声明绑定变量 OUTRES 那么 如何定义绑定变量OUTRES以及在哪里定义呢 usr bin bash sqlplus s scott tiger lt lt EOF declare
  • 如何使用索引更改表的列?

    我想将带有某些索引的表中 a 列的列大小从 varchar 200 更改为 varchar 8000 我应该如何进行 既然是VARCHAR你正在增加尺寸 然后简单地ALTER TABLE ALTER COLUMN https learn m
  • SQL Server:删除具有外键约束的行:事务可以覆盖约束吗?

    我有一些添加了外键约束的表 它们与代码生成一起使用 以在生成的存储过程中设置特定的联接 是否可以通过在事务中调用多个删除来覆盖这些约束 特别是 C 中的 TransactionScope 或者绝对需要级联删除吗 不要使用级联删除 这样可能会
  • 自定义 Sql Server 对象资源管理器右键单击菜单项

    如何在 Sql Server 2012 的对象资源管理器中添加或自定义右键菜单项 例如 我想将新项目添加到表右键菜单中以生成自定义表创建器脚本 您可以编写一个 SSMS 加载项 See http sqlblogcasts com blogs
  • 有没有一种简单的方法来获取 .NET 为参数化查询生成的“sp_executesql”查询?

    背景 如果我有以下程序 public class Program public static void Main using var connection new SqlConnection Server local Database Te
  • 如何将嵌套对象数组转换为 CSV?

    我有一个包含嵌套对象的数组 例如 name 1 children name 1 1 children 1 2 id 2 thing name 2 1 children 2 2 name 3 stuff name 3 1 children 3

随机推荐