3

これがテーブルです

  user_id | parent_id | lft
  --------|-----------|-----
        1 |           | 0
        2 |         1 | 0
        3 |         1 | 0
        4 |         2 | 0

ノード 1 から CTE を実行し、リーフに到達するまで user_id 1 のすべての子をトラバースし、トラベスされた chidren lft フィールドの値を 1 に更新するクエリを次に示します。

WITH RECURSIVE d AS (
  SELECT user_id
   FROM btrees
   WHERE user_id = 1
 UNION ALL
  SELECT c.user_id
   FROM d JOIN btrees c ON c.parent_id = d.user_id
)
UPDATE btrees b set lft = 1
 FROM d
 WHERE d.user_id = b.user_id

反対方向に進むクエリを求めているだけです..つまり。lft の値を更新できるように、任意のノードからルート ノードに

4

1 に答える 1

5

あるノードからルートまでのすべてのノードを更新するクエリは、非常によく似ています。

WITH RECURSIVE d AS (
  SELECT user_id
   FROM btrees
   WHERE user_id = :node_id
 UNION ALL
  SELECT c.user_id
   FROM d JOIN btrees c ON d.parent_id = c.user_id
)
UPDATE btrees b set lft = 1
 FROM d
 WHERE d.user_id = b.user_id

結合の条件が逆になることに注意してください。

一般に、再帰クエリは次のように機能します。

  1. レコードの開始セットは、WITH RECURSIVE 句内の UNION ALL の最初の選択によって決定されます。
  2. UNION ALL の 2 番目の選択は、これまでに見つかったレコードから次のレベルのレコードを取得する方法を定義します。上から下にトラバースすると、このクエリはすべての子を見つける必要があります。下から上にトラバースすると、親が見つかるはずです。
  3. ステップ 2 は、繰り返しで新しいレコードが追加されなくなるまで実行されます。
于 2013-10-28T21:47:42.143 に答える