SQL query to resolve transitive dependencies in database

ぃ、小莉子 提交于 2019-12-06 04:10:13

问题


SQLFIddle link for this data.

Suppose I have a table with following Structure:

create table rd(r1 number,r2 number, primary key (r1,r2));

Sample Data:

| R1 | R2 |
-----------
|  1 |  2 |
|  1 |  4 |
|  2 |  3 |
|  3 |  1 |
|  4 |  5 |

What it means is that R1 is related to R2 , bi-directionally. So if there is an entry in database for 1,3 there won't be an entry like 3,1.

According to above data: 1 is related to 2,4,3 directly. And 4 is related to 1 also . So via transitive dependency, 1 and 5 are also considered as related.

Expected result:

| R1 | R2 |
-----------
|  1 |  2 |
|  1 |  4 |
|  1 |  3 |
|  1 |  5 |

Can anyone write a SQL query for this?


回答1:


As you are running Oracle 11g (and If it happens to be Release 2), as one of the methods, you can use recursive common table expression (also known as recursive sub-query factoring) to get desired result.

SQL> with rcte(r1, r2, lv, root) as(
  2    select r1
  3         , r2
  4         , 0 lv
  5         , r1
  6     from rd
  7    where r1 = 1
  8  
  9    union all
 10  
 11    select t.r1
 12         , t.r2
 13         , lv + 1
 14         , q.root
 15      from rd   t
 16      join rcte q
 17        on (t.r1 = q.r2)
 18  )
 19  search depth first by r1 set s
 20  cycle r1 set is_cycle to 'y' default 'n'
 21  
 22  select root
 23       , r2
 24    from rcte
 25  where is_cycle = 'n'
 26    and r2 <> root
 27  ;

      ROOT         R2
---------- ----------
         1          2
         1          3
         1          4
         1          5



回答2:


The following query will work as long as there is only one level of intermediate values in the table.

It works by expanding the table into a monodirectional one, and then combining that table with the results of joining it to itself.

WITH expanded AS
  (SELECT r1, r2 FROM rd
   UNION ALL
   SELECT r2 AS r1, r1 AS r2 FROM rd)
SELECT * FROM
  (SELECT r1, r2 FROM expanded     -- direct relations
   UNION
   SELECT e1.r1 AS r1, e2.r2 AS r2 -- indirect relations
   FROM expanded e1
   INNER JOIN expanded e2
   ON e1.r2 = e2.r1                -- via transitive dependency
   AND e2.r2 <> e1.r1)
WHERE r1 = 1
ORDER BY r1, r2


来源:https://stackoverflow.com/questions/13548988/sql-query-to-resolve-transitive-dependencies-in-database

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!