postgresqlの再帰クエリ


開発では、サブノードを再帰的にクエリーする必要がある場合がよくあります.以前はmysqlを使用していましたが、具体的な機能はありません.
 
しかしpostgresqlには強力なwithクエリ文があります.
 
WITHは、より大きなSELECTクエリでサブクエリを記述する方法を提供する.この一般的に共通テーブル式またはCTEsと呼ばれるサブクエリは、クエリに定義された一時テーブルとみなすことができる.この特性の1つの応用は,複雑なクエリを単純な部分に分解するために用いられる.
 
再帰クエリ評価
評価には再帰用語がありません.UNION(UNIOALLではない)を使用して、重複する行を削除します.再帰クエリの結果に残りのすべてのローを含め、一時的なワークシートに配置します.
ワークシートが空でない場合は、次の手順を繰り返します.
再帰用語を評価し、現在のワークシートの内容を再帰自己参照に置き換えます.UNION(UNIOALLではない)で、重複する行と、以前の結果行と重複する行を除去します.再帰クエリの結果に残っているすべてのローを含め、一時的な中間テーブルに配置します.
ワークシートの内容を中間テーブルの内容に置き換え、中間テーブルを空にします.

Note:厳密に言えば、このプロセスは再帰ではなく反復ですが、RECURSIVEはSQL標準委員会を通じて選択された用語です.
オプションのRECURSIVE修飾子は、文法的な利便性だけでなく、仕事を完成させる特性の変更まで使用できます.RECURSIVEを使用すると、WITHクエリは独自の出力を参照できます.
 
簡単な例は、クエリが1から100に加算された和です.
WITH RECURSIVE t(n) AS (
    VALUES (1)
  UNION ALL
    SELECT n+1 FROM t WHERE n < 100
)
SELECT sum(n) FROM t;

再帰クエリを使用する場合は、クエリの再帰部分が最終的にメタグループに戻らないことを確認することが重要です.そうしないと、クエリはループします.
例を見てみましょう
with recursive cte as (
            select * from cn_product_menu where menu_id=123 union all
            select b.* from cn_product_menu b inner join cte c on b.parent_id=c.menu_id)
            select menu_id from cte;

テーブルcn_が得られたproduct_menuでmenu_id=123下のすべての子(孫)menu_id