6

条件が真になるまで、指定された値から開始してデータベースを「ループ」するクエリを作成しようとしています。たとえば、TABLE の例に次のエントリがあるとします。

id, parent, cond
1,        , True
2, 1      , False
3, 1      , False
4, 2      , False
... ... ...

入力として (たとえば) 4 を受け取り、2 と 1 の値を返すクエリが必要です。プロセスは、クエリが ID に一致し、cond==False の場合、親 (id = 2 )。2 行目の cond = False であるため、「親」ID が選択されます (1)。ここで最初の行を見ると、cond=True であるため、LOOP が終了し、1 と 2 が返されます。

私はそのクエリを知っています

SELECT parent FROM example WHERE id = 4;

親ID 2を生成します。

したがって、LOOPを作成する私の無駄な試み:

WHILE (SELECT cond FROM example) = False
LOOP SELECT parent FROM example WHERE id = 4 
END LOOP;

まず、これによりエラーが発生します (「'while' で、またはその近くで構文エラーが発生しました」)。第二に、反復ごとに「id」を更新する方法がわかりません。

Python のようなプログラミング言語では、4 に初期化された変数を使用し、反復ごとに更新することがあります... Postgres で同等のことを行う方法がわかりません。

ご不明な点や追加情報が必要な場合はお知らせください。ありがとう!

4

1 に答える 1

11

あなたの考えはSQLにとって間違っています。ループや条件、変数の観点から考えないでください。代わりに、必要なデータを記述する方法を考えてください。トリッキーな部分は、クエリがそれ自体の結果を参照するようにすることです。これが再帰CTEの目的です。

オプションのRECURSIVE修飾子WITHは、単なる構文上の利便性から、標準SQLでは不可能なことを実現する機能に変わります。を使用するRECURSIVEと、WITHクエリはそれ自体の出力を参照できます。

あなたはこのようなものを探しています:

with recursive path as (
    select id, parent from T where id = 4
    union all
    select t.id, t.parent from T t join path p on t.id = p.parent
)
select id, parent
from path

それはあなたにこれを与えるでしょう:

 id | parent 
----+--------
  4 |      2
  2 |      1
  1 |       

次に、データベースの外部でよりリンクされたリスト(またはクライアント言語で適切なもの)になるパスにそれを戻すことができます。もちろん含める必要はありませんが、含めるparentと「ポインタ」を修正するのに役立ちます。

于 2012-08-07T07:07:55.710 に答える