来年はじめのリリースを目指して開発中のPostgreSQL 8.4の姿が見え始めてきた。今回は8.4の新機能の目玉の一つである「再帰SQLのサポート」を中心にお話しする。

 開発にあたっては,PostgreSQLの大規模利用ユーザーである住友電工情報株式会社がリソースを提供し,筆者の勤務するSRA OSS日本支社がPostgreSQLコミュニティとの調整および実装を担当した。最終的にはPostgreSQLコアメンバらの協力で実装がブラッシュアップされ,8.4への取り込みが確定した。

プログラミング言語における再帰処理

 再帰処理はCやJavaなどの通常のプログラミングでは普通にサポートされており,うまく使うと効率のよいプログラムをきれいに書くことができる。再帰処理は再帰的な構造を持つデータ,例えば木構造やリスト構造を処理する際に良く使われる。

データベースにおける再帰処理

 再帰SQLとは,文字通りSQL文を使ってこのような再帰処理を行うことを指す。SQLはもともと集合演算に基づく関係代数をサポートするために開発された言語であり,手続き的な概念である再帰とはなじみが薄く,オブジェクト指向的機能などと同様,SQL標準の世界でサポートされたのはわりと最近のことで,2003年にリリースされたSQL:2003からになる。SQL標準の再帰SQLをサポートしている製品は,商用データベースではDB2,SQL Serverなど,オープンソースデータベースでは筆者が知る限り Firebirdがある(Oracleは独自構文で再帰SQLを実装している)。

WITH句とは

 SQL標準の構文で再帰処理を行うには,「WITH句」というものを使う。なじみが薄い読者もいるかもしれないので,簡単に説明しよう。WITH句は以下のように書く。

WITH [RECURSIVE] AS (共通テーブル式) 問合わせ本体;

 問合わせ本体は普通のSELECT文で,「共通テーブル式」には,名前を付けた問合わせの定義を書く。この名前は「共通テーブル式名」と呼ばれ,「問合わせ本体」の中でテーブル式として引用できる。複雑なSELECT文を一度定義しておいて再利用するという意味では,ビューに良く似ている。ビューとの違いはその定義が該当SQL文の中だけで有効だという点だ。わざわざビューを作るまでもない時に便利だと言えよう。

 ここで「RECURSIVE」というキーワードを使えば再帰的な定義を記述できるが,まずは再帰を含まない場合を見ていこう。

再帰を含まないWITH句

 非常に単純なWITH句の例を示す。

WITH w1 AS (SELECT * FROM t1) SELECT * FROM w1;

 (SELECT * FROM t1)が共通テーブル式で,それに付けた名前がw1である。そして,問合わせ本体がSELECT * FROM w1になる。結局,上のSQLは

SELECT * FROM t1;

 を回りくどい方法で実行しているに過ぎないが,WITH句の書式はご理解頂けたと思う。

この先は会員の登録が必要です。有料会員(月額プラン)は初月無料!

日経 xTECHには有料記事(有料会員向けまたは定期購読者向け)、無料記事(登録会員向け)、フリー記事(誰でも閲覧可能)があります。有料記事でも、登録会員向け配信期間は登録会員への登録が必要な場合があります。有料会員と登録会員に関するFAQはこちら