SQLでブール式を使うと
真理値型をサポートしているDBMSの場合
各DBMSにおける真理値型のサポートが遅れているという状況は、SQLの文法にも影響を与えています。たとえば、こんな簡単なクエリですら問題が起きます。図3の人名と住んでいる国のテーブルから、日本に住んでいるかどうかを結果に出力したいと思います。
図3 人名、住んでいる国テーブル
name (名前) | state (国) |
太郎 | Japan |
ジョン | USA |
カール | Germany |
ギャビー | Mexico |
源三郎 | Japan |
パオロ | Italia |
もしSQLがSELECT句でブール式の評価をサポートしていれば、リスト1のクエリは問題なく通るはずです(図4)。
真理値型をサポートしていないDBMSの場合
しかし、ご想像のとおり、このクエリが通るのはPostgreSQLとMySQLのみです(MySQLの場合、結果の表示が0/1で行われます)。残るDBは真理値をサポートしていない以上、結果セットの中に真理値が含まれることを許容するわけもないので、エラーになります。
もし真理値をサポートしないDBで同じような結果が欲しいと思うなら、リスト2のようにCASE式で無理やり文字型として返すしかないでしょう。
これはすべてのDBで実行できます。ただし、あくまで文字列として「true」とか「false」と書いているだけですので、この値を使ってAND/ORの論理演算ができるわけではありません。
これはDBエンジニアにとって大きなデメリットです。プログラミング言語から論理演算を奪うというのは、片手を縛ってボクシングをするようなものです。何とかうまい方法はないものでしょうか。
ビット演算で代用する
実はここに1つ、代替となる方法があります。それは、MySQLも部分的にやっているように、0/1の整数値によるビット演算で論理演算を代用することです。
- 論理演算 ビット演算
- AND → かけ算
- OR → 足し算
そうすると、「false AND true = false」は「0 * 1 = 0」と等価ですし、「true OR false = true」は、「1 + 0 = 1」と等価になります。気をつけなければならないのは、「true OR true = true」を模倣する「1 + 1」の結果が2になってしまうことです。これは、DB側にビット型というデータ型があるわけではなく、ただの整数値を使っているだけですので、しかたありません。ともあれ、少々すっきりしないものの、これでSQLで論理演算を行うことが可能になります。
それでは、SQLで論理演算を駆使した場合、どのような応用が可能になるか、見ていきましょう。