【发布时间】:2020-05-22 09:32:07
【问题描述】:
我有以下数据:
表:
CREATE TABLE tblLoop
(
person1 varchar(20),
person2 varchar(20),
ColDate date,
);
INSERT INTO tblLoop VALUES('A','B','2020-01-01'),('A','C','2020-01-01'),('A','D','2020-01-01'),
('B','E','2020-01-02'),('B','F','2020-01-02'),
('D','G','2020-01-03'),('D','H','2020-01-03'),
('F','i','2020-01-04'),
('G','J','2020-01-05'),
('i','A','2020-01-06'),
('J','D','2020-01-07'),
('X','Y','2020-01-08'),('X','Z','2020-01-08'),
('Z','X','2020-01-09'),
('Y','W','2020-01-09');
记录看起来像:
要求:我需要找到形成循环的人。对于给定数据中的示例,我们发现了 3 个循环:
循环 1:A 连接到 B 连接到 F 连接到 i 连接到 A。
循环 2:A 连接到 D 连接到 G 连接到 J 连接到 D。
循环 3:X 连接到 Z 连接到 X。
预期结果:
LoopFound
--------------------
A->B->F->i->A
A->D->G->J->D
X->Z->X
我的尝试:
;WITH CTE AS
(
SELECT Person1, Person2,
CONVERT(VARCHAR(MAX), (','+ Person1+ ','+ Person2+ ',')) AS nodes, 1 AS lev,
(CASE WHEN Person1 = Person2 THEN 1 ELSE 0 END) AS has_cycle
FROM tblLoop e
UNION ALL
SELECT cte.Person1, e.Person2,
CONVERT(VARCHAR(MAX), (cte.nodes+ e.Person2+ ',')), lev + 1,
(CASE WHEN cte.nodes LIKE ('%,'+ e.Person2+ ',%') THEN 1 ELSE 0 END) AS has_cycle
FROM CTE
JOIN tblLoop e ON e.Person1 = cte.Person2
WHERE cte.has_cycle = 0
)
SELECT *
FROM CTE
WHERE has_cycle = 1;
注意:从上述查询中获取多个循环组合。
【问题讨论】:
-
我建议,如果可能的话,在你的表中添加一个额外的标志,表明 A 和 X 是根人。在您的 SELECT 语句中,您只能过滤这些人的组合。
标签: sql-server tsql sql-server-2012