为什么在WHERE子句中对被连接的表添加条件时,LEFT JOIN会返回更少的行?
我想把所有客户列出来,并在他们有订单时显示他们的订单。如果某个客户没有订单,我仍然想在结果中看到这个客户。
CREATE TABLE customers (
customer_id INT,
customer_name VARCHAR(50)
);
CREATE TABLE orders (
order_id INT,
customer_id INT,
order_date DATE
);
INSERT INTO customers VALUES
(1, 'Alice'),
(2, 'Bob'),
(3, 'Charlie');
INSERT INTO orders VALUES
(101, 1, '2025-01-10'),
(102, 1, '2025-02-15'),
(103, 2, '2024-12-20');
我获取了所有客户,包括没有订单的Charlie:
SELECT c.customer_id, c.customer_name, o.order_date
FROM customers c
LEFT JOIN orders o
ON c.customer_id = o.customer_id;
但当我添加一个日期过滤条件:
SELECT c.customer_id, c.customer_name, o.order_date
FROM customers c
LEFT JOIN orders o
ON c.customer_id = o.customer_id
WHERE o.order_date >= '2025-01-01';
Charlie从结果中消失,而LEFT JOIN表现得像INNER JOIN。
为什么在WHERE子句中添加条件会改变LEFT JOIN的行为?
在按日期过滤订单的同时,怎样才能保留没有订单的客户?
解决方案
答案是因为null在WHERE子句中被视为假值。
你可以通过比较来测试这一点:
SELECT 1 WHERE true;
-- vs
SELECT 1 WHERE null;
你在WHERE子句中发生了null,因为你已经执行了LEFT JOIN,然后再与右表中的一列进行比较。那意味着左表中没有在右表中匹配到行的行,对应的右表中的所有列都会是null。最后,对null的任何比较(除了IS (NOT) null)都会得到null。
也就是说,给定这一行:
customer_id | customer_name | order_date
-------------+---------------+------------
3 | Charlie |
你的WHERE子句中的o.order_date >= '2025-01-01'将导致null,这意味着该行不会成为返回的行集合的一部分。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。