Skip to content

sql-not

NOT 运算符是 SQL 中的一个逻辑运算符,用于反转任何布尔表达式的结果。如果一个条件是 TRUE,NOT 会使其变为 FALSE;如果它是 FALSE,NOT 会使其变为 TRUE。它对于从结果集中排除特定数据至关重要。

NOT 运算符在 WHERE 子句中使用,用于过滤掉满足特定条件的行。为避免歧义,最好将要否定的条件用括号括起来。

首先,让我们设置我们的示例 CUSTOMERS 表:

CREATE TABLE CUSTOMERS(
ID INT PRIMARY KEY,
NAME VARCHAR(100) NOT NULL,
AGE INT,
ADDRESS CHAR(25),
SALARY DECIMAL(18, 2)
);
INSERT INTO CUSTOMERS VALUES
(1, 'Ramesh', 32, 'Ahmedabad', 2000.00),
(2, 'Khilan', 25, 'Delhi', 1500.00),
(3, 'Kaushik', 23, 'Kota', 2000.00),
(4, 'Chaitali', 25, 'Mumbai', 6500.00),
(5, 'Hardik', 27, 'Bhopal', 8500.00),
(6, 'Komal', 22, 'Hyderabad', 4500.00),
(7, 'Muffy', 24, 'Indore', 10000.00),
(8, 'John Doe', NULL, 'Nowhere', NULL);

以下查询检索所有薪水不大于 2000.00 的客户。这包括薪水小于或等于 2000.00 的客户。

SELECT * FROM CUSTOMERS WHERE NOT (SALARY > 2000.00);
IDNAMEAGEADDRESSSALARY
1Ramesh32Ahmedabad2000.00
2Khilan25Delhi1500.00
3Kaushik23Kota2000.00

注意:SALARY 为 NULL 的行不会被返回,因为 NULL > 2000.00 求值为 UNKNOWN,并且 NOT (UNKNOWN) 也为 UNKNOWN。

NOT LIKE 运算符用于查找不匹配指定字符串模式的记录。这对于排除不符合特定格式的名称、代码或文本很有用。

-- 查找姓名不以 'K' 开头的客户
SELECT * FROM CUSTOMERS WHERE NAME NOT LIKE 'K%';

NOT IN 运算符检索列值不在给定值列表中的行。

-- 查找年龄不是 25 或 32 的客户
SELECT * FROM CUSTOMERS WHERE AGE NOT IN (25, 32);

请注意:如果 NOT IN 中的列表包含 NULL 值,查询可能不会返回任何行,因为其逻辑可能不直观。通常使用 NOT EXISTS 更安全。

IS NOT NULL 条件用于选择在特定列中具有非空(即已定义)值的行。

-- 查找年龄已定义的客户
SELECT * FROM CUSTOMERS WHERE AGE IS NOT NULL;

此查询排除了年龄为 NULL 的 ‘John Doe’。

IDNAMEAGEADDRESSSALARY
1Ramesh32Ahmedabad2000.00
2Khilan25Delhi1500.00
3Kaushik23Kota2000.00
4Chaitali25Mumbai6500.00
5Hardik27Bhopal8500.00
6Komal22Hyderabad4500.00
7Muffy24Indore10000.00

NOT BETWEEN 选择超出给定范围(范围本身是包含性的)的值。

-- 查找薪水不在 2000 到 8000 之间的客户
SELECT * FROM CUSTOMERS
WHERE SALARY NOT BETWEEN 2000.00 AND 8000.00;

NOT EXISTS 检查子查询中是否存在行。它通常是比 NOT IN 更高效、更安全的替代方案,尤其是在处理可能返回 NULL 值的子查询时。

让我们查找所有从未下过订单的客户。我们需要一个 ORDERS 表。

CREATE TABLE ORDERS(
OID INT PRIMARY KEY,
CUSTOMER_ID INT NOT NULL,
AMOUNT DECIMAL(18, 2)
);
INSERT INTO ORDERS VALUES
(102, 3, 3000.00),
(100, 3, 1500.00),
(101, 2, 1560.00),
(103, 4, 2060.00);

NOT EXISTS 查询通常非常高效。

-- 使用 NOT EXISTS(推荐)
SELECT ID, NAME FROM CUSTOMERS c
WHERE NOT EXISTS (
SELECT 1 FROM ORDERS o
WHERE o.CUSTOMER_ID = c.ID
);

实现相同结果的另一种常见且易读的模式是使用 LEFT JOIN 并检查 JOIN 右侧的 NULL 值。

-- 使用 LEFT JOIN / IS NULL(也是一个很好的选择)
SELECT c.ID, c.NAME FROM CUSTOMERS c
LEFT JOIN ORDERS o ON c.ID = o.CUSTOMER_ID
WHERE o.OID IS NULL;

这两个查询都将返回在 ORDERS 表中没有任何匹配记录的客户。

IDNAME
1Ramesh
5Hardik
6Komal
7Muffy
8John Doe