LEFT JOIN是SQL中常用的连接操作,但对其条件放置(ON vs WHERE)的误解易导致查询错误。本文通过核心要点和可复现实例,解析两者差异。
❗
通常用于一对一的关联关系,当一对多时需要额外关注条件以免不符合预期
LEFT JOIN 以左表为基准,返回所有行。右表无匹配时,字段补 NULL。
ON 后的条件,将左表的每一行与右表进行匹配。NULL。✅ 关键:左表的所有行都会保留,无论是否匹配成功。
JOIN 完成后,对整个上一步完整结果集应用 WHERE 条件,过滤掉不符合条件的行。ON left_table.id = right_table.id AND left_table.col = 'value'):左表所有行返回,仅影响右表匹配。WHERE left_table.col = 'value'):可能减少左表返回行数。场景:查询用户及其订单(订单金额大于150)
表结构:
users(左表):id, nameorders(右表):id, user_id, amount数据准备:
-- 用户表(左表)
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(10)
);
INSERT INTO users VALUES
(1, 'Alice'),
(2, 'Bob'),
(3, 'Charlie');
-- 订单表(右表)
CREATE TABLE orders (
id INT PRIMARY KEY,
user_id INT,
amount DECIMAL(5,2)
);
INSERT INTO orders VALUES
(101, 1, 100.00),
(102, 1, 200.00), -- Alice 有两笔订单
(103, 2, 50.00);
users:
id | name
1 | Alice
2 | Bob
3 | Charlie
orders:
id | user_id | amount
101 | 1 | 100
102 | 1 | 200
103 | 2 | 50
SELECT users.name, orders.amount
FROM users
LEFT JOIN orders ON users.id = orders.user_id;
-- 结果
name | amount
Alice | 200
Alice | 100
Bob | 50
Charlie | Null
SELECT users.name, orders.amount
FROM users
LEFT JOIN orders ON users.id = orders.user_id
WHERE orders.amount > 150; -- 会过滤掉无订单的用户
-- 结果
name | amount
Alice | 200 -- 匹配订单
SELECT users.name, orders.amount
FROM users
LEFT JOIN orders ON (users.id = orders.user_id AND orders.amount > 150);
# 结果
name | amount
Alice | 200 -- 匹配订单
Bob | NULL -- 金额≤150的订单被ON条件排除,但左表行保留
Charlie | NULL -- 无订单,右表补NULL
LEFT JOIN的左表基准特性。验证方式:使用任意SQL数据库(如MySQL、PostgreSQL)创建上述表结构并插入示例数据,执行查询即可复现结果。