4

このデータの SQLFiddle リンク。

次の構造を持つテーブルがあるとします。

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

サンプルデータ:

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

これが意味することは、R1 が R2 に双方向で関連付けられているということです。したがって、データベースに 1,3 のエントリがある場合、3,1 のようなエントリはありません。

上記のデータによると、1 は 2、4、3 に直接関係しています。そして 4 は 1 とも関連しています。したがって、推移的な依存関係を介して、1 と 5 も関連していると見なされます。

期待される結果:

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

誰でもこれに対する SQL クエリを作成できますか?

4

2 に答える 2

3

Oracle 11g (およびリリース 2 の場合) を実行しているため、方法の 1 つとして、再帰的な共通テーブル式 (再帰的なサブクエリ ファクタリングとも呼ばれます)を使用して、目的の結果を得ることができます

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
于 2012-11-25T08:46:17.737 に答える
0

次のクエリは、テーブルに中間値のレベルが1つしかない限り機能します。

これは、テーブルを単方向のテーブルに拡張し、そのテーブルをそれ自体に結合した結果と組み合わせることによって機能します。

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
于 2012-11-25T11:31:19.070 に答える