Quantcast
Channel: SQL.ru: Microsoft SQL Server
Viewing all articles
Browse latest Browse all 7251

Транзитивное замыкание через T-SQL

$
0
0
Всем здравствуйте.

Задача:
Есть таблица с парами значений. Необходимо дополнить её значениями, исходя из транзитивности оных. То есть, если x=y, а y=z, то x=z. Пары в таблице могут быть рефлективны, а могут и нет – тогда нужно дополнить набор, чтобы все пары были рефлективны. То есть, если есть x=y, то должна быть и y=x.

Я понимаю, что это можно сделать процедурно.
Но интересно, можно ли это сделать через T-SQL?

Попытался, но вижу, что неверно - не все варианты в результате...

WITH
t AS
  (SELECT 'x' AS a, 'y' AS b
   UNION ALL
   SELECT 'y' AS a, 'x' AS b
   UNION ALL 
   SELECT 'y' AS a, 'z' AS b
   UNION ALL 
   SELECT 'z' AS a, 'y' AS b
   UNION ALL 
   SELECT 'm' AS a, 'n' AS b
   UNION ALL 
   SELECT 'm' AS a, 'z' AS b),
 
coupled_reflective AS

  (SELECT t2.a, t2.b
   FROM t t1
   JOIN t t2 ON t1.a=t2.b
   AND t1.b!=t2.a),

reversive_coupled_reflective AS

  (SELECT t2.b, t2.a
   FROM t t1
   JOIN t t2 ON t1.a=t2.b
   AND t1.b!=t2.a),

rs AS

  (SELECT *
   FROM coupled_reflective
   UNION
   SELECT *
   FROM t
   EXCEPT
   SELECT *
   FROM reversive_coupled_reflective),

 cte AS

  (SELECT a, b
   FROM rs
   UNION ALL
   SELECT rs.b, cte.b
   FROM rs
   JOIN cte ON rs.a=cte.a
   AND rs.b!=cte.b),

 cte2 AS

  (SELECT a, b
   FROM rs
   UNION ALL
   SELECT rs.a, cte.a
   FROM rs
   JOIN cte ON rs.b=cte.b
   AND rs.a!=cte.a)



SELECT a, b FROM cte2
UNION
SELECT b, a FROM cte2
UNION
SELECT a, b FROM cte
UNION
SELECT b, a FROM cte
UNION
SELECT a, b FROM t
UNION
SELECT b, a FROM t

Viewing all articles
Browse latest Browse all 7251

Trending Articles