もしサブクエリが行を返せば、EXISTS
は
subqueryTRUE で、NOT EXISTS
は
subqueryFALSE です。例:
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
ですか?」
に答える、と言う方が簡単です。
