如果子查询返回任何行,则 EXISTS subquery 为 TRUE,NOT EXISTS subquery 为 FALSE。例如:
1. SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);
一般来说,EXISTS 子查询以 SELECT * 开头,但它可以用 SELECT 5、SELECT column1 或其他任何内容开头。MySQL 在这样的子查询中忽略 SELECT 列表,因此没有任何区别。
对于前面的示例,如果 t2 包含任何行,甚至包含只有 NULL 值的行,则 EXISTS 条件为 TRUE。这实际上是一个不太可能的例子,因为 [NOT] EXISTS 子查询几乎总是包含相关性。下面是一些更现实的例子:
● 在一个或多个城市中有什么样的商店?
1. SELECT DISTINCT store_type FROM stores
2. WHERE EXISTS (SELECT * FROM cities_stores
3. WHERE cities_stores.store_type = stores.store_type);
● 任何城市都不没有的是什么类型的商店?
1. SELECT DISTINCT store_type FROM stores
2. WHERE NOT EXISTS (SELECT * FROM cities_stores
3. WHERE cities_stores.store_type = stores.store_type);
● 所有城市都有的商店是什么商店?
1. SELECT DISTINCT store_type FROM stores s1
2. WHERE NOT EXISTS (
3. SELECT * FROM cities WHERE NOT EXISTS (
4. SELECT * FROM cities_stores
5. WHERE cities_stores.city = cities.city
6. AND cities_stores.store_type = stores.store_type));
最后一个例子是一个双重嵌套的 NOT EXISTS 查询。也就是说,它在 NOT EXISTS 子句中有一个 NOT EXISTS 子句。从形式上说,它回答了“一个城市是否存在一个没有在 Stores 表中的商店”?但是更容易说的是,嵌套的 NOT EXISTS 回答了问题“x 对所有 y 都是真的吗?”
在 MySQL 8.0.19 及更高版本中,也可以在子查询中使用带有 TABLE 的 NOT EXISTS 或 NOT EXISTS,如下所示:
1. SELECT column1 FROM t1 WHERE EXISTS (TABLE t2);
结果与在子查询中使用不带 WHERE 子句的 SELECT * 相同。
官方网址:
https://dev.mysql.com/doc/refman/8.0/en/exists-and-not-exists-subqueries.html