首页 > 解决方案 > 用于返回链的 SQL 查询

问题描述

我有一个跟踪变化的表。一列被调用beforename,另一列被调用aftername

一些样本数据可能是:

家长 孩子
一个 b
b C
C d

我正在尝试编写一个查询,该查询将以返回更改的方式自我引用自身,即:

a -> b -> c -> d (the arrows are just for notation here)

这可以在 SQL 中完成吗?

我的数据库是 SQL Server

标签: sqlsql-servertsqlhierarchychaining

解决方案


您可以使用递归公用表表达式 (CTE);

WITH cte(Root, Level, Parent, Child) AS (
  SELECT Parent, 0, Parent, Child FROM Table1 
     WHERE Parent NOT IN (SELECT Child FROM Table1)
  UNION ALL
  SELECT cte.Root, cte.Level + 1, t1.Parent, t1.Child 
  FROM cte 
  JOIN Table1 t1 
     ON cte.Child = t1.Parent AND cte.Level < 10
)
SELECT * FROM cte ORDER BY Root, Level;

基本上,递归 CTE 使用基本案例(找到所有起点)。这个用;

SELECT Parent, 0, Parent, Child FROM Table1 
     WHERE Parent NOT IN (SELECT Child FROM Table1)

...找到所有父母,即在表格中从未提及父母作为孩子的行。然后它将这些父级设置为“根”并将级别设置为 0。

然后它继续使用以下方法查找该根的子行;

SELECT cte.Root, cte.Level + 1, t1.Parent, t1.Child 
  FROM cte 
  JOIN Table1 t1 
     ON cte.Child = t1.Parent AND cte.Level < 10

...它基本上只是找到下一个子元素(以该行子元素为父元素的行),同时保持根并将级别增加 1。

它还将递归限制为 10 级,以防万一数据中存在循环。

一个用于测试的 dbfiddle


推荐阅读