为什么在WHERE子句中对被连接的表添加条件时,LEFT JOIN会返回更少的行?

编程语言 2026-07-11

我想把所有客户列出来,并在他们有订单时显示他们的订单。如果某个客户没有订单,我仍然想在结果中看到这个客户。

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的行为?

在按日期过滤订单的同时,怎样才能保留没有订单的客户?

解决方案

答案是因为nullWHERE子句中被视为假值。

你可以通过比较来测试这一点:

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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章