sql-server - SQL Server 查找两列之间的链
问题描述
我有一张这样的桌子:
from | to
-----+-----
23 | 24
24 | 25
25 | 27
27 | 30
45 | 46
46 | 47
50 | 52
53 | 60
我需要一个 SQL Server 查询来检测链并返回每个链中的最小值(从)和最大值(到)(也是具有一条记录的链):
from | to
-----+-----
23 | 30
45 | 47
50 | 52
53 | 60
解决方案
这是一种使用递归 CTE 的方法。
CREATE TABLE #chainLinks(linkFrom INTEGER, linkTo INTEGER);
INSERT INTO #chainLinks VALUES (23,24);
INSERT INTO #chainLinks VALUES (24,25);
INSERT INTO #chainLinks VALUES (25,27);
INSERT INTO #chainLinks VALUES (27,30);
INSERT INTO #chainLinks VALUES (45,46);
INSERT INTO #chainLinks VALUES (46,47);
INSERT INTO #chainLinks VALUES (50,52);
INSERT INTO #chainLinks VALUES (53,60);
WITH reccte AS
(
/*Recursive Seed*/
SELECT linkFrom AS chainStart,
linkFrom,
linkTo,
0 as links
FROM #chainLinks as chainLinks
WHERE linkFrom NOT IN (SELECT DISTINCT linkTo FROM #chainLinks)
UNION ALL
/*Recursive Term*/
SELECT
reccte.chainStart,
chainLinks.linkFrom,
chainLinks.linkTo,
links + 1
FROM reccte
INNER JOIN #chainLinks as chainLinks ON reccte.linkTo = chainLinks.linkFrom
)
SELECT chainStart, linkTo AS chainEnd
FROM
(
SELECT chainStart, linkFrom, linkTo, links, ROW_NUMBER() OVER (PARTITION BY chainStart ORDER BY links DESC) AS rn
FROM reccte
)subrn
WHERE rn = 1;
递归 CTE 包含两个部分
- 递归种子 - 这是
UNION
我们确定表中哪些记录开始递归的部分。在这里,我们想要任何linkFrom
不是linkTo
- 一个 recursive 术语 - 这是
UNION
我们加入cte 的下面的部分,reccte
回调到原始表。这部分 CTE 反复迭代,直到连接失败。
在这里,我们还跟踪links
只是我们为获得该输出记录而经历的迭代次数的计数器。links
我们为每个起点保留最高数量chainStart
。
推荐阅读
- python-3.x - 查找图像中颜色的交集和对称差异
- swift - GameCenter 排行榜不更新分数
- powerbi - PowerBI、DAX、填充地图视觉。如何创建度量以获取每个地理区域的最常见值
- repository - DDD:如何防止购买在没有相关撤回的情况下被持久化
- laravel - 在没有 php artisan serve 的情况下运行项目时,Laravel Debugbar 不起作用
- c# - 如何从 WPF RichTextBox 获取所有编号列表
- java - Java流averagingInt由多个参数
- reactjs - React-three-fiber, useSpring - 在一个元素上一个接一个地运行 2 个不同的动画
- javascript - 如何有效地在另一个数组中找到一个数组的对象?
- node.js - 使用 Firebase 函数和 Firebase 托管进行动态渲染