“左连接(LEFT JOIN)出现重复数据”是 SQL 里非常常见的问题,本质原因通常是:右表(被连接表)存在多条匹配左表同一行记录的数据。
下面从原因 → 解决思路 → 常见场景示例给你讲清楚。
假设有两张表:
users(左表)
| id | name |
|---|---|
| 1 | 张三 |
| 2 | 李四 |
orders(右表)
| id | user_id | amount |
|---|---|---|
| 1 | 1 | 100 |
| 2 | 1 | 200 |
| 3 | 2 | 300 |
执行:
SELECT u.id, u.name, o.amount
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;
结果:
| id | name | amount |
|---|---|---|
| 1 | 张三 | 100 |
| 1 | 张三 | 200 |
| 2 | 李四 | 300 |
✅ 这是正常行为:张三有 2 笔订单,所以被复制成 2 行。
如果你只想每个左表一行,就先对右表聚合。
SELECT
u.id,
u.name,
COUNT(o.id) AS order_count,
SUM(o.amount) AS total_amount
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
GROUP BY u.id, u.name;
✅ 适合:统计、汇总场景
比如只取最新一笔订单:
SELECT
u.id,
u.name,
o.amount
FROM users u
LEFT JOIN (
SELECT user_id, amount
FROM orders
WHERE id = (
SELECT MAX(id)
FROM orders o2
WHERE o2.user_id = orders.user_id
)
) o ON u.id = o.user_id;
或(MySQL 8+ / PostgreSQL):
LEFT JOIN (
SELECT *, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY id DESC) rn
FROM orders
) o ON u.id = o.user_id AND o.rn = 1
✅ 适合:只关心“一条”关联数据
如果重复是因为连接条件不全:
SELECT DISTINCT u.id, u.name
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;
⚠️ 注意:
常见错误:
ON u.id = o.id -- 错!应该是 user_id
或漏了关键条件:
ON u.id = o.user_id AND o.status = 1
✅ 很多时候“重复”其实是连接条件不全
| 你的目标 | 推荐方案 |
|---|---|
| 统计数量 / 金额 | 聚合(GROUP BY) |
| 只取一条关联记录 | 子查询 / ROW_NUMBER |
| 单纯去重显示 | DISTINCT |
| 怀疑 SQL 写错 | 检查 ON 条件 |
你可以把:
发出来,我可以直接帮你改 SQL ✅
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。