我正在运行以下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的汽车两次。如何更改查询以使所有结果都是唯一的(没有重复)?
答案 0 :(得分:14)
您可以尝试 SELECT DISTINCT
而不是 SELECT
答案 1 :(得分:5)
在查询末尾添加group by cars.id
EG:
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)
GROUP BY cars.id
答案 2 :(得分:0)
假设cars.id
是唯一的主键,其中一个连接会导致笛卡尔积。也就是说:wheels
或manuals
包含cars.id = 27
的多个匹配。
子查询通常是消除笛卡尔积的好工具。下面的示例查询显示了两种使用子查询的方法。
第一个子查询确保我们只查看带有黑色轮子的汽车,该记录是在2011年5月1日之前创建的。 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)