SELECT 文の基本的な形式は、敢えて説明するまでもありませんが、
SELECT 表示する列のリスト
FROM 検索元となる表
WHERE 検索条件
ですね。
今回はこの FROM 句に注目してみたいと思います。
FROM 句を省略することが可能な RDBMS と省略できない RDBMS があります。
PostgreSQL、MySQL など主な OSS-DB と一部の商用 RDBMS では省略可能ですが、代表的な商用 RDBMS である Oracle と DB2 では FROM 句を省略できません。
ところで、SELECT はそもそも、表からデータを検索するために使うはずのものなのに、検索元の表を指定しない、というのは、どういうことなのでしょうか。
実は、いろいろなケースがあります。
最も簡単なのは、SELECT を電卓代わりに使う場合です。例えば、1日は何秒か、という計算(60 * 60 * 24)をするのに、SQL を使って
SELECT 60 * 60 * 24;
とすることができます。この計算にはデータベースの表を参照する必要はありませんよね。
計算式を実行するのでなく、データベースに組み込まれた関数を呼び出すこともできます。
SELECT current_timestamp;
とすれば、現在日時を表示してくれます。組み込みの関数だけでなく、自作のストアドプログラムの呼び出しでも同じように使えます。
また、ポイント・イン・タイム・リカバリ(PITR)の機能を使うためにベースバックアップを取得するとき、バックアップの前後に、
SELECT pg_start_backup('label');
SELECT pg_stop_backup();
を実行しますが、これらは、何かの結果を表示することではなく、関数として実装された手続きを実行することが目的になっています。
FROM 句を省略するが WHERE 句は省略しない、ということもあります。文字列リテラルの項でも説明しましたが、
SELECT 1 WHERE '' = '';
SELECT 1 WHERE '' IS NULL;
のような使い方で、動作検証などのテストをすることもできます。
ところで、FROM 句を省略できないデータベースで同じことをするにはどうしたら良いのでしょうか。簡単に言ってしまうと、何でも良いから実在するテーブルを FROM に指定すれば良いです。これは、FROM 句を省略できるデータベースでも実験できます。例えば、
CREATE TABLE test (id INTEGER, val VARCHAR(20));
INSERT INTO test (id, val) VALUES (1, 'abc');
として、新しい表 test を作成し、
SELECT 60 * 60 * 24 FROM test;
SELECT current_timestamp FROM test;
などとやってみてください。FROM 句を省略した時と同じ結果になるはずです。
では、更に
INSERT INTO test (id, val) VALUES (2, 'xyz');
として、データを追加したあとで、同じ SELECT 文を実行したらどうなりますか。あるいは、
DELETE FROM test;
として、表からすべてのデータを削除してから、同じ SELECT 文を実行したらどうでしょう。INSERT の後は2行、同じものが表示されます。一方で、DELETE の後は何も表示されないので、計算結果や現在日時がわかりません。
もう、おわかりでしょう。
SELECT 文は表のデータを検索して表示するためのものですが、表示する列のリストとして指定するものは、必ずしも表のデータである、あるいは表のデータと関連したものである必要はありません。WHERE 句も同じで、必ずしも表のデータと関連したものである必要はありません。
FROM 句で指定した表のそれぞれの行について、WHERE 句の条件を評価し、結果が真であったすべての行(WHERE 句が省略されれば、表のすべての行)について SELECT のリストで指定した内容を表示する、というのが SELECT 文の基本動作ですが、リストの内容が単なる計算式のような表のデータと関係しないものの場合、表とは無関係な同じ内容を、表の行数と同じ回数だけ繰り返し表示することになります。つまりデータが100行あれば100回表示しますし、1行もなければ1回も表示しません。
というわけで、データが1行だけある表があって、それを FROM 句に指定すれば、FROM 句を省略した場合と同じ結果が得られます。表の列(データ型と列の数)や行データの内容は何でもあってもよく、データが1行だけ存在する、ということがポイントです。
FROM 句を省略できない RDBMS では、そのような表をダミー表として用意していて、そのダミー表を FROM 句に指定することになっています。例えば、Oracleではダミー表として dual という表を使いますが、この表が FROM 句に指定された時に、データベースが特別な動作をするわけではありません。データが1行だけある、小さな表が存在しているのです。Oracle が利用できる場合は、sqlplus でデータベースに接続して
SELECT * FROM dual;
とすれば確認できます。
解説:松田神一
© EDUCO All Rights Reserved.