[pgsql-jp: 33794] Re: 効率的なSQL について
Mao Morimoto
yneko2 @ yamamaya.com
2004年 8月 4日 (水) 12:47:40 JST
もりもとです。
アルゴリズムは苦手なんですが・・
以前同じようなことを(SQLではなくてオンメモリで)やったことがあるので、
それを元に少々・・
まず、ノード同士の直接の接続を表すデータを用意します。
<<table T_NODE>>
GEN LEFT RIGHT HOP
---------------------
1 A B 1
1 B C 1
1 B D 1
1 C E 1
GENは接続の世代番号、HOPは接続の中継数(+1)です。
ここに、第1世代のRIGHTと第1世代以上のLEFTがおなじ物同士を結びつけた、
第2世代のレコードを作成します。こんなSQLで。
INSERT INTO T_NODE
( GEN, LEFT, RIGHT, HOP )
SELECT 2, T1.LEFT, T2.RIGHT, T1.HOP + T2.HOP
FROM T_NODE T1, T_NODE T2
WHERE T1.RIGHT = T2.LEFT AND
T2.GEN >= 1
これで、追加されるレコードは3レコード
GEN LEFT RIGHT HOP
---------------------
2 A C 2
2 A D 2
2 B E 2
次に、第1世代のRIGHTと第2世代以上のLEFTがおなじ物同士を結びつけた、
第3世代のレコードを作成します。こんなSQLで。(上のSQLと2文字違うだけ
です)
INSERT INTO T_NODE
( GEN, LEFT, RIGHT, HOP )
SELECT 3, T1.LEFT, T2.RIGHT, T1.HOP + T2.HOP
FROM T_NODE T1, T_NODE T2
WHERE T1.RIGHT = T2.LEFT AND
T2.GEN >= 2
これで、追加されるレコードは1レコード
GEN LEFT RIGHT HOP
---------------------
3 A E 3
これを、結合するレコードがなくなるまで延々と繰り返します。
繰り返す回数は、中継する回数の最大までなので、1個1個つながりをみていくより
は
だいぶ効率的・・かと。ただし、ループがあると無限ループになってしまうので、
その辺は別途考慮が必要かも・・。
これが全部終われば、ノード間のすべての接続を表すデータができあがるので、
その後でノード間の接続を調べるのは、ずっと効率的、になります。。
- Mao Morimoto
http://blog.yamamaya.com/
pgsql-jp メーリングリストの案内