SQLにおける存在仮定の原理

またもやSQLで??????ってなったのちに納得したので書く。

混乱したこと

要素が全てNULLのテーブル

user_id user_name
NULL NULL
NULL NULL
NULL NULL

ここで、「NullTableにuser_id=1のレコードが1つでも存在するか?」を確認する以下のSQL

SELECT (1 = ANY(SELECT user_id FROM NullTable)) AS any_null_result;
any_null_result
UNKNOWN

また、「NullTableのすべてのuser_idは1であるか?」を確認するSQLとその結果は以下になる。

SELECT (1 = ALL(SELECT user_id FROM NullTable)) AS all_null_result;
all_null_result
UNKNOWN

all_null_resultもany_null_resultもUNKNOWNとなる。SQLにおけるNULLは、「将来的に値が決まるかもしれないけど現時点では不明」を表すので、直感的にも正しい。

空のテーブル

では次は、要素が空のテーブルを考える。

user_id user_name

ここで、さきほどと同様に、まずは、「EmptyTableにuser_id=1のレコードが1つでも存在するか?」を確認するSQLとその結果は以下のようになる。

SELECT (1 = ANY(SELECT user_id FROM EmptyTable)) AS any_empty_result;
any_empty_result
FALSE

EmptyTableにレコードが存在しないので、当然user_id=1のレコードも存在しないので、これは当たり前。

問題は次。「EmptyTableのすべてのuser_idは1であるか?」を確認するSQLとその結果。

SELECT (1 = ALL(SELECT user_id FROM EmptyTable)) AS all_empty_result;
all_empty_result
TRUE

???

SQL「すべてのユーザのIDは1です!(ユーザがいるとは言っていない)」

みたいなね。きっつー。でもこれは正しい。

なんでこうなるか

SQLは存在仮定の原理に従うから。

例えば、ぼくは好きな人と付き合えるのかという命題を考えるときに、好きな人がいることを前提としていいのか?でも命題でちゃんと言ってないやん?空気読めってこと?厳密性皆無やん?ということで、古く論理学において議論の種だったらしい。

現代ではそれは「前提としない」ということになっている。好きな人が存在しない場合というのは、単に部分命題にすぎないという整理。

例えば、「ぼくは好きな人と付き合える」という文がTRUEだとすると、以下のように帰納的に理解できる。

  • 好きな人が3人いる場合: 3人と付き合える => TRUE
  • 好きな人が2人いる場合: 2人と付き合える => TRUE
  • 好きな人が1人いる場合: 1人と付き合える => TRUE
  • 好きな人が0人いる場合: 0人と付き合える => TRUE (好きな人が存在しない場合)

3人と付き合えるなら2人とも当然付き合えるし、それなら1人と付き合えるってことだし、じゃあ0人とも付き合える!みたいなね。

これを前段での例に当てはめると以下になる。

  • ユーザが0人いる場合: 0人のuser_idが1 => TRUE

そういうかんじ。

スマブラ強いやつが偉い

ニンテンドウオールスター! 大乱闘 スマッシュブラザーズ

ニンテンドウオールスター! 大乱闘 スマッシュブラザーズ

同世代の共通認識だと思うけど、スマブラ強いやつが一番偉い。なんだかんだで。スマブラ弱いやつが何を言っても説得力がない。スマブラ弱いくせに、ってなる。

ガーリィレコードという芸人コンビの、スマブラのワンシーンを再現した動画がTwitterで流れてきた。爆笑した。で、昨日無限大ホールで生のネタをみた。ファルコンとマリオの漫才。爆笑した。

参考