我有一个这样的表:
from | to
-----+-----
23 | 24
24 | 25
25 | 27
27 | 30
45 | 46
46 | 47
50 | 52
53 | 60
Run Code Online (Sandbox Code Playgroud)
我需要一个 SQL Server 查询来检测链并返回每个链中的最小(从)和最大(到)(也是具有一条记录的链):
from | to
-----+-----
23 | 30
45 | 47
50 | 52
53 | 60
Run Code Online (Sandbox Code Playgroud)
这是一种使用递归 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;
Run Code Online (Sandbox Code Playgroud)
递归 CTE 分为两部分
UNION递归种子 - 这是我们确定表中哪些记录开始递归的部分。在这里我们想要任何linkFrom不是linkToUNIONcte的下面的部分。reccteCTE 的这一部分会一遍又一遍地迭代,直到连接失败。在这里,我们还跟踪它,links它只是我们为获取输出记录而经历的迭代次数的计数器。links我们保留每个起点的最大数量chainStart。
这是工作示例: https: //rextester.com/JWUW57837
| 归档时间: |
|
| 查看次数: |
1239 次 |
| 最近记录: |