Skip to content

MySQL - NOT 运算符

MySQL NOT 是一个逻辑运算符,用于否定布尔表达式。它会反转其后条件的真值。如果一个条件为真,则 NOT condition 变为假。如果一个条件为假,则 NOT condition 变为真。它通常用于 WHERE 子句中,以选择不满足特定条件的行。

例如,如果您想查找所有 不 住在 ‘California’ 的客户,您可以使用 NOT 运算符将该特定州从结果中排除。

为了清晰并避免运算符优先级问题,最佳实践是将您要否定的条件括在括号中,例如 WHERE NOT (condition)。

NOT 运算符在 SELECT 语句中的基本语法是:

SELECT column1, column2, ...
FROM table_name
WHERE NOT condition;

让我们使用 CUSTOMERS 表进行示例。

CREATE TABLE CUSTOMERS(
ID INT AUTO_INCREMENT PRIMARY KEY,
NAME VARCHAR(100) NOT NULL,
AGE INT NOT NULL,
ADDRESS VARCHAR(100),
SALARY DECIMAL(10, 2)
);
INSERT INTO CUSTOMERS(NAME, AGE, ADDRESS, SALARY) VALUES
('Ramesh', 32, 'Ahmedabad', 2000.00),
('Khilan', 25, 'Delhi', 1500.00),
('Kaushik', 23, 'Kota', 2000.00),
('Chaitali', 25, 'Mumbai', 6500.00),
('Hardik', 27, 'Bhopal', 8500.00),
('Komal', 22, 'Hyderabad', 4500.00),
('Muffy', 24, 'Indore', 10000.00);

以下查询选择所有地址 不是 ‘Hyderabad’ 的客户。

SELECT * FROM CUSTOMERS
WHERE NOT ADDRESS = 'Hyderabad';

将 NOT 与比较和逻辑运算符结合使用

Section titled “将 NOT 与比较和逻辑运算符结合使用”

NOT 运算符用途广泛,并且经常与其他运算符结合使用,例如 IN、IS NULL、LIKE 和 BETWEEN。

使用 NOT IN 排除列表中任何值都不匹配的行。

SELECT * FROM CUSTOMERS
WHERE NAME NOT IN ('Khilan', 'Chaitali', 'Muffy');

使用 IS NOT NULL 查找特定列有值(即不为 NULL)的行。

SELECT * FROM CUSTOMERS
WHERE ADDRESS IS NOT NULL;

使用 NOT LIKE 排除不匹配特定字符串模式的行。

-- Find customers whose name does not start with 'K'
-- 查找姓名不以 'K' 开头的客户
SELECT * FROM CUSTOMERS
WHERE NAME NOT LIKE 'K%';

使用 NOT BETWEEN 选择超出指定范围的行。

SELECT * FROM CUSTOMERS
WHERE AGE NOT BETWEEN 25 AND 30;

在 DML 语句(UPDATE, DELETE)中使用 NOT

Section titled “在 DML 语句(UPDATE, DELETE)中使用 NOT”

NOT 运算符在 UPDATE 和 DELETE 语句中同样有用,可用于定位除特定子集以外的所有行。

以下查询更新所有年龄 不在 25 到 30 之间的客户的薪水。

UPDATE CUSTOMERS
SET SALARY = SALARY * 1.10
WHERE AGE NOT BETWEEN 25 AND 30;

此查询删除所有 不 来自 ‘Mumbai’ 或 ‘Delhi’ 的客户。

DELETE FROM CUSTOMERS
WHERE ADDRESS NOT IN ('Mumbai', 'Delhi');

这是一个关键且常见的陷阱。如果 NOT IN 子句中的列表包含 NULL 值,则整个表达式将永远不会评估为真。这是因为与 NULL 的比较(如 x <> NULL)会导致 UNKNOWN,而 NOT UNKNOWN 也是 UNKNOWN。查询将意外地返回零行。

-- This will ALWAYS return an empty set because of the NULL!
-- 这将始终返回空集,因为存在 NULL!
SELECT * FROM CUSTOMERS
WHERE ID NOT IN (1, 2, NULL);

为避免这种情况,请始终确保 NOT IN 子句中的子查询或列表不会产生 NULL 值,或者改用 NOT EXISTS 子查询,后者可以正确处理 NULL。

NOT 是一个逻辑运算符,它否定整个布尔表达式。!=(或 <>) 是一个比较运算符,用于检查不相等。虽然 NOT col = 'val' 等效于 col <> 'val',但 NOT 更强大,因为它可以否定复杂的表达式:

WHERE NOT (AGE > 30 AND ADDRESS = 'Delhi');

在应用程序代码中使用 NOT 运算符

Section titled “在应用程序代码中使用 NOT 运算符”

在应用程序中构建查询时,您可以像在直接 SQL 中一样使用 NOT 运算符。一如既往,使用预处理语句来防止 SQL 注入。

PHP (PDO)
Node.js (mysql2)
Java (JDBC)
Python (mysql-connector)
Use a prepared statement to securely pass values to your query.
```php
<?php
// ... (PDO connection setup)
// ... (PDO 连接设置)
try {
$pdo = new PDO($dsn, $user, $pass, $options);
$sql = "SELECT * FROM CUSTOMERS WHERE ADDRESS IS NOT NULL AND AGE NOT BETWEEN ? AND ?;";
$stmt = $pdo->prepare($sql);
$stmt->execute([25, 30]);
foreach ($stmt->fetchAll() as $row) {
print_r($row);
}
} catch (\PDOException $e) { /* ... error handling ... */ }
// ...错误处理...
?>

Use mysql2/promise for clean, asynchronous code.

const mysql = require('mysql2/promise');
async function getFilteredCustomers(minAge, maxAge) {
let connection;
try {
connection = await mysql.createConnection({ /* ... connection config ... */ });
// ...连接配置...
const sql = 'SELECT * FROM CUSTOMERS WHERE ADDRESS IS NOT NULL AND AGE NOT BETWEEN ? AND ?;';
const [rows] = await connection.execute(sql, [minAge, maxAge]);
console.log(rows);
} catch (error) {
console.error('Query failed:', error);
// 查询失败:
} finally {
if (connection) await connection.end();
}
}
getFilteredCustomers(25, 30);

Use a PreparedStatement to safely include parameters in your WHERE clause.

import java.sql.*;
public class NotOperatorExample {
public static void main(String[] args) {
String sql = "SELECT * FROM CUSTOMERS WHERE ADDRESS IS NOT NULL AND AGE NOT BETWEEN ? AND ?;";
try (Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setInt(1, 25);
stmt.setInt(2, 30);
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
System.out.printf("ID: %d, Name: %s, Age: %d%n",
rs.getInt("ID"), rs.getString("NAME"), rs.getInt("AGE"));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

Pass parameters as a tuple to the cursor’s execute method.

import mysql.connector
config = { /* ... connection config ... */ }
// ...连接配置...
def get_filtered_customers(min_age, max_age):
try:
with mysql.connector.connect(**config) as cnx:
with cnx.cursor(dictionary=True) as cursor:
query = ("SELECT * FROM CUSTOMERS "
"WHERE ADDRESS IS NOT NULL AND AGE NOT BETWEEN %s AND %s")
cursor.execute(query, (min_age, max_age))
for row in cursor.fetchall():
print(row)
except mysql.connector.Error as err:
print(err)
get_filtered_customers(25, 30)