MySQL Как вернуть уникальные/отличные результаты?

Я запускаю следующий запрос 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)

Результаты запроса выглядят правильно, но он возвращает автомобиль с идентификатором 27 дважды. Как изменить запрос, чтобы все результаты были уникальными (без дубликатов)?

Ответ 1

Вы можете попробовать SELECT DISTINCT вместо SELECT

Ответ 2

добавить group by cars.id в конце запроса НАПРИМЕР: SELECT cars. * FROM cars INNER JOIN колеса ON cars.id = wheels.car_id Руководства LEFT OUTER JOIN ON cars.id = manuals.car_id WHERE (cars.created_at > '2010-09-09' AND wheels.color = 'Black' AND wheels.created_at < '2011-01-05' И manuals.car_id IS NULL) GROUP BY cars.id Код >

Ответ 3

Предполагая, что cars.id является уникальным первичным ключом, одно из этих объединений вызывает декартово произведение. То есть: wheels или manuals содержат более одного соответствия для cars.id = 27.

Подзапросы часто являются хорошим инструментом для устранения декартовых произведений. В приведенном ниже примере ниже показаны два метода использования подзапросов.

  • Первый подзапрос гарантирует, что мы смотрим только на автомобили с черными колесами, где эта запись была создана до 01/05/2011. Предложение 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)