我正在运行以下MySQL查询,以查找没有手册(且车轮有黑轮等)的汽车
SELECT `cars`.* FROM `cars` INNER JOIN wheels ON cars.id = wheels.car_id LEFT OUTER JOIN manuals ON cars.id = manuals.car_id WHERE (cars.created_at > '2010-09-09' AND wheels.color = 'Black' AND wheels.created_at < '2011-01-05' AND manuals.car_id IS NULL)
查询的结果看起来正确,但是它两次返回ID为27的汽车。如何更改查询,以使所有结果都是唯一的(没有重复项)?
假定这cars.id是唯一的主键,那么其中的一种联接将导致笛卡尔乘积。也就是说:wheels或manuals包含多个匹配项cars.id = 27。
cars.id
wheels
manuals
cars.id = 27
子查询通常是消除笛卡尔积的好工具。下面的示例查询显示了两种使用子查询的方法。
第一个子查询可确保我们只查看在2011年1月5日之前创建了该记录的黑色车轮汽车。该GROUP BY子句可确保我们每个仅返回一个记录w.car_id。
GROUP BY
w.car_id
第二个子查询(有时称为相关子查询)可确保在主查询中没有找到每辆汽车的手册。
未经测试,但传达了以下想法:
SELECT `cars`.* FROM `cars` JOIN ( SELECT w.car_id FROM wheels w WHERE w.color = 'Black' AND w.created_at < '2011-01-05' GROUP BY w.car_id ) wheels ON cars.id = wheels.car_id WHERE cars.created_at > '2010-09-09' AND NOT EXISTS (SELECT m.car_id FROM manuals m WHERE m.car_id = cars.id)