【SQL】再帰with句

再帰

再帰(さいき)は、あるものについて記述する際に、記述しているものそれ自身への参照が、その記述中にあらわれることをいう。

ウィキペディア

有名なフィボナッチ関数も自分自身を呼んでますね。

def f(x)
  p x
  if x <= 1
      x
  else
      f(x - 1) + f(x - 2)
  end
end

p("result:" + f(5).to_s)

$ ruby fib.rb 
5
4
3
2
1
0
1
2
1
0
3
2
1
0
1
"result:5"

こういった再帰処理を、with句を使ったSQLでできます。

再帰with句

最後にご紹介するサイトはoracleですが、手元のsqliteでやってみました。

sqliteoracleのようにdual表がないのでfrom dual というのは省略です。

with rec(Val) as(
-- 初期クエリ
select 1
union all
-- 再帰クエリ
select Val+1
  from rec
 where Val+1 <= 5)
-- メインクエリ
select Val from rec;

sqlite> with rec(Val) as(
   ...> -- 初期クエリ
   ...> select 1
   ...> union all
   ...> -- 再帰クエリ
   ...> select Val+1
   ...>   from rec
   ...>  where Val+1 <= 5)
   ...> -- メインクエリ
   ...> select Val from rec;
1
2
3
4
5

union all の上を非再帰項、下が再帰項と呼びます。

最初に再帰項(初期クエリ)が実行され、

その結果を使って再帰クエリを実行し、

その結果を使って再帰クエリを、、と、 再帰クエリの結果が0件になるまで行います。

これを使えば、たとえば組織同士の親子関係を持つ表から、ある組織の子孫まで取得できそうですね。

参考

www.oracle.com