もしサブクエリが行を返せば、EXISTS
は
subquery
TRUE
で、NOT EXISTS
は
subquery
FALSE
です。例:
SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);
もともと、EXISTS
サブクエリは
SELECT *
で開始しますが、SELECT 5
や
SELECT
column1
、またそれ以外のどんな物でも開始する事ができます。MySQL
はそのようなサブクエリの中では
SELECT
リストを無視するので、何も変わらないのです。
先ほどの例では、もし t2
が
NULL
値しか含まない物でも良いので、何かの行を含むのなら、EXISTS
の条件は TRUE
となります。[NOT] EXISTS
サブクエリは通常相互関係を持つので、実際はこれはよくあるような例ではありません。ここに、もう少し現実的な例があります。
複数の町には、どんな種類のお店がありますか?
SELECT DISTINCT store_type FROM stores WHERE EXISTS (SELECT * FROM cities_stores WHERE cities_stores.store_type = stores.store_type);
町ではないところには、どんな種類のお店がありますか?
SELECT DISTINCT store_type FROM stores WHERE NOT EXISTS (SELECT * FROM cities_stores WHERE cities_stores.store_type = stores.store_type);
全ての町には、どんな種類のお店がありますか?
SELECT DISTINCT store_type FROM stores s1 WHERE NOT EXISTS ( SELECT * FROM cities WHERE NOT EXISTS ( SELECT * FROM cities_stores WHERE cities_stores.city = cities.city AND cities_stores.store_type = stores.store_type));
最後の例は、二重にネスト化された NOT
EXISTS
クエリです。それは、NOT
EXISTS
条項の中に NOT EXISTS
条項を持っている、という事です。これは、正式に次の質問
「Stores
にはないお店がある町は存在しますか」?
という質問に答えます。しかし、ネスト化した
NOT EXISTS
が、次の質問
「x
は全ての
y
に TRUE
ですか?」
に答える、と言う方が簡単です。