You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

执行三表LEFT JOIN查询出现重复记录,如何调整SQL获取预期结果

问题原因

你遇到的9条重复记录是一对多关联产生的笛卡尔积导致的:

  • employee与coffee_shop通过shop_id关联时,两者是一对一/多对一关系,单条员工记录只会匹配到唯一的门店记录,因此两表关联返回3条结果符合预期。
  • 当你额外关联coffee表时,同一个shop_id对应了3条coffee记录,单条员工+门店的组合会匹配到同门店下的所有3条咖啡记录,3*3=9就是你当前拿到的结果。

解决方案

根据你期望返回3条记录的需求,提供两种常用实现方案:

方案1:聚合同门店的咖啡信息

如果需要保留同门店的所有咖啡信息,可以用聚合函数将多条咖啡数据合并为单个字段返回,适合需要展示门店所有咖啡的场景:

SELECT 
  e.*,
  cs.*,
  -- 可按需调整聚合逻辑,比如用GROUP_CONCAT合并咖啡名称,用MAX取最高售价等
  GROUP_CONCAT(DISTINCT c.coffee_name SEPARATOR '、') AS shop_coffee_list,
  MAX(c.price) AS max_coffee_price
FROM employee e 
LEFT JOIN coffee_shop cs ON e.shop_id = cs.shop_id 
LEFT JOIN coffee c ON cs.shop_id = c.shop_id
-- 按员工唯一ID分组,保证每个员工只返回1条记录
GROUP BY e.employee_id

方案2:先对coffee表按门店去重再关联

如果你只需要每个门店匹配1条咖啡记录(比如任意一条、最新上架的、售价最高的),可以先处理coffee表,保证每个shop_id只有1条记录后再关联:

SELECT e.*, cs.*, c.* 
FROM employee e 
LEFT JOIN coffee_shop cs ON e.shop_id = cs.shop_id 
LEFT JOIN (
  -- 子查询先按shop_id分组,保证每个门店只有1条咖啡记录
  SELECT * FROM coffee GROUP BY shop_id
) c ON cs.shop_id = c.shop_id

如果使用MySQL 8.0+版本,还可以用窗口函数更灵活的筛选单条咖啡:

SELECT e.*, cs.*, c.* 
FROM employee e 
LEFT JOIN coffee_shop cs ON e.shop_id = cs.shop_id 
LEFT JOIN (
  SELECT *,
    -- 按shop_id分区,按售价倒序排序取第一条,即每个门店最贵的咖啡
    ROW_NUMBER() OVER(PARTITION BY shop_id ORDER BY price DESC) AS rn 
  FROM coffee
) c ON cs.shop_id = c.shop_id AND c.rn = 1

内容的提问来源于stack exchange,提问作者WHOATEMYNOODLES

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 08:39:03