HOWTO · MySQL

使用 EXISTS 和 IF() 检查 MySQL 中是否存在某一行

使用 EXISTS 检查 MySQL 中的行是否符合条件,然后使用 IF() 返回易读的结果。

本页内容

要检查 MySQL 中是否存在某一行,可以将 EXISTS 谓词与子查询结合使用。当子查询至少返回一行时,它为真。将其放入 MySQL 的 IF() 函数中,可以选择 Yes, exists 或 No, does not exist 这样的值。本指南介绍 EXISTS 谓词和 IF() 函数;DDL 语句中的 IF EXISTS 是另外的语法。

MySQL 示例使用一个小型 student_details 表。在尝试这些查询之前,请先在 MySQL 会话中运行这些设置语句:

CREATE TABLE student_details (stu_id INT PRIMARY KEY, stu_firstName VARCHAR(255), stu_lastName VARCHAR(255));

INSERT INTO student_details (stu_id, stu_firstName, stu_lastName) VALUES (1, 'Preet', 'Sanghavi'), (2, 'Rich', 'John'), (3, 'Veron', 'Brow'), (4, 'Geo', 'Jos'), (5, 'Hash', 'Shah'), (6, 'Sachin', 'Parker'), (7, 'David', 'Miller');

这个自包含的 Python 示例使用 SQLite 的内置库来检查 ID 4。观察到的输出如下所示;本指南中的 MySQL 查询应在 MySQL 中运行。

import sqlite3

connection = sqlite3.connect(":memory:")
connection.execute("CREATE TABLE student_details (stu_id INTEGER PRIMARY KEY)")
connection.executemany(
    "INSERT INTO student_details (stu_id) VALUES (?)",
    [(1,), (2,), (3,), (4,)],
)
result = connection.execute(
    "SELECT EXISTS (SELECT 1 FROM student_details WHERE stu_id = ?)", (4,)
).fetchone()[0]
print(result)
connection.close()
1

MySQL 中 EXISTS 运算符的基本用法

EXISTS 测试其子查询是否返回行。子查询中选择的值不会成为结果;SELECT 1 清楚地表明了这一目的。在 MySQL 中,用以下语句检查 ID 4:

SELECT EXISTS (SELECT 1 FROM student_details WHERE stu_id = 4) AS RESULT;

结果为 1,因为示例表中包含 stu_id = 4。将条件改为 stu_id = 11,则返回 0。这些预期的 MySQL 结果来自设置数据;上面的 Python 示例是在 SQLite 中演示该谓词,而不是在 MySQL 中。

该条件检查 stu_id,与名字的值无关。当存在性测试适合该操作时,同样的谓词可以用在更大的 SELECT、UPDATE、DELETE 或 INSERT 语句中。对于是或否的查询结果,SELECT EXISTS (...) 返回 MySQL 的数值真值或假值。

SELECT EXISTS (...) 返回包含 1 或 0 的一行,当应用程序需要单个是或否的值时很有用。若只想返回另一个表中具有相关匹配的行,可以将 EXISTS 放在外部查询的 WHERE 子句中。例如,SELECT c.customer_id FROM customers AS c WHERE EXISTS (SELECT 1 FROM orders AS o WHERE o.customer_id = c.customer_id); 返回至少有一个匹配订单的客户。对 c.customer_id 的引用使子查询与每个候选客户行相关联。请使用您自己架构中的表名和键名。

在 MySQL 中将 IF() 与 EXISTS 结合使用

MySQL 的 IF(condition, value_if_true, value_if_false) 在两个值中选择一个。使用 EXISTS 作为其条件,可以为 ID 4 返回易读的结果:当查询应直接返回标签或其他值时,IF() 很有用;除非其结果被用于过滤条件,否则它不会改变所选择的行。两个结果参数可以是字符串、数字或其他兼容的表达式。

SELECT IF(EXISTS (SELECT 1 FROM student_details WHERE stu_id = 4), 'Yes, exists', 'No, does not exist') AS RESULT;

对于 ID 4 的示例行,RESULT 为 Yes, exists。对于像 11 这样缺失的 ID,将条件改为 stu_id = 11;RESULT 为 No, does not exist。这些预期值来自示例行和 MySQL 表达式语义;SQLite 演示并不会执行 MySQL 的 IF() 函数。

RESULT 是为返回的值加标签的列别名。更改子查询的 WHERE 条件以检查其他 ID 或标准,并使用与您的表匹配的列名。对于更大的查询,请检查其计划,并使用您的数据和索引进行测量。成本取决于查询和架构,因此不存在 EXISTS 总是很慢,或者必须对每个外部行以某种固定方式重新运行的一般规则。