4

我正在运行以下 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 的汽车。如何更改查询以使所有结果都是唯一的(不重复)?

4

3 回答 3

15

你可以尝试SELECT DISTINCT而不是SELECT

于 2011-01-11T22:11:32.093 回答
6

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
于 2011-01-11T22:10:10.477 回答
3

假设这cars.id是一个唯一的主键,其中一个连接导致笛卡尔积。也就是说:要么 要么wheels包含manuals多个匹配项cars.id = 27

子查询通常是消除笛卡尔积的好工具。下面的示例查询显示了使用子查询的两种方法。

  1. 第一个子查询确保我们只查看在 2011 年 1 月 5 日之前创建该记录的带有黑色车轮的汽车。该GROUP BY子句确保我们只返回一个记录w.car_id

  2. 第二个子查询(有时称为相关子查询)确保在主查询中没有为每辆汽车找到手册。

未经测试,但传达了这个想法:

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)
于 2011-01-11T22:32:17.197 回答