SQLで真理値表を表示
SQLで真理値表を表示する方法について記述します。
SQLでと言いつつ、postgresqlでしか試していませんのでご注意ください。
2値論理
with truth_tables as ( select true tv union all select false ) select tt1.tv t1, tt2.tv t2, tt1.tv and tt2.tv land, tt1.tv or tt2.tv lor from truth_tables tt1, truth_tables tt2 ;
実行結果
t1 | t2 | land | lor ----+----+------+----- t | t | t | t t | f | f | t f | t | f | t f | f | f | f (4 rows)
いわゆる普通の真理値表を返します。
3値論理
with truth_tables as ( select true tv union all select false union all select null ) select tt1.tv t1, tt2.tv t2, tt1.tv and tt2.tv land, tt1.tv or tt2.tv lor, tt1.tv = tt2.tv eq from truth_tables tt1, truth_tables tt2 ;
実行結果
t1 | t2 | land | lor | eq ----+----+------+-----+---- t | t | t | t | t t | f | f | t | f t | | | t | f | t | f | t | f f | f | f | f | t f | | f | | | t | | t | | f | f | | | | | | (9 rows)
true,false以外にnullを取りうる3値論理版です。
ポイントは何と言ってもnullでしょう。特にnull=null
がnull
になることに注意が必要です。この事実を知らないと、下記のようなSQLを書きがちです。
select * from hoge_tables where a = 1 and b = 2 and c = null and d = 4;
このSQLを書いた人はカラムaが1、bが2、cがnull、dが4である行を取得することを期待してると思いますが、c = nullを満たすようなことはないために思い通りに取得できなくなってしまいます。null比較は専用の演算があります。
select * from hoge_tables where a = 1 and b = 2 and c is null and d = 4;
nullの比較にはイコールでなくis nullを使うということはよく説明されてるように思います。 何故そのようなことをする必要があるかをSQLにおける論理演算を通して理解するのも良いかと思います。
おまけ
is nullも真理値表に組み込みたいと思って、下記のようにするとエラーになりました。
select tt1.tv is tt2.tv t1_is_t2 from truth_tables tt1, truth_tables tt2 ;
「そりゃそうか」と思いましたが、次に「いや、これだとis nullだけじゃなくてis trueも考えることになる。そもそもis true
なんてあるのか?」という疑問が浮かび上がってきました。
試してみます。
select true is true;
実行結果
?column? ---------- t (1 row)
あるやんけ。 調べてみると、参考[3]の通り、{expression} is [true|false|null]などの構文があるようです(つまり{expression} is {expression}はダメ)。
null以外であれば、普通にイコール比較すれば良いので、is trueとis falseの使いどころはいまいち分からないですね...
参考
[1] https://www.postgresql.org/docs/13/datatype-boolean.html
[2] https://www.postgresql.org/docs/13/functions-logical.html
[3] https://www.postgresql.org/docs/13/functions-comparison.html