Как выполнить поиск при объединении 3 таблиц, но исключить результат для одной из них?

Я уже несколько часов пытаюсь получить конкретный результат и не нашел ответа в Интернете, и, поскольку я не эксперт по SQL вообще, я задаю вопрос здесь .

У меня есть 3 таблицы: user (id, name...), cars (id, type, color, engine power...) и промежуточная таблица для сохранения всех оценок, которые пользователи поставили машине: scores (id, user_id, car_id , score).

Я пытаюсь найти запрос, который мог бы вернуть для одного конкретного пользователя все автомобили, которые еще не оценили. Я пробовал следующее, но он возвращает ноль:

$q=mysql_query("SELECT * FROM cars LEFT OUTER JOIN scores ON cars.id = scores.car_id WHERE scores.user_id != ('".$userId."')");

Кто-нибудь знает?


person BoDeX    schedule 27.08.2011    source источник


Ответы (3)


SELECT
  *
FROM
  cars
WHERE
  NOT EXISTS (SELECT 1 FROM scores WHERE car_id = cars.id AND user_id = ?)

где ? — идентификатор этого конкретного пользователя.

Здесь полезен составной индекс в scores по (car_id, user_id).

person Tomalak    schedule 27.08.2011
comment
Вау, все отлично работает, огромное спасибо! Я проверю составной индекс, о котором вы говорили, никогда раньше его не использовал... - person BoDeX; 27.08.2011

Вы можете использовать свой код с небольшой модификацией:

SELECT * FROM cars 
LEFT OUTER JOIN scores ON cars.id = scores.car_id and scores.user_id=".$userId."
WHERE scores.id IS NULL
person Andrej Ludinovskov    schedule 27.08.2011
comment
+1 Это альтернатива. ИМХО не так выразительно, как НЕ СУЩЕСТВУЕТ. - person Tomalak; 27.08.2011
comment
@Zapadlo Не могли бы вы объяснить свой комментарий? Что совсем :) неверно в этом запросе? Я думаю, прежде чем публиковать такой комментарий, вы должны больше узнать о sql и левом соединении :) - person Andrej Ludinovskov; 28.08.2011
comment
@Zapadlo Согласен, я перепутал машины и баллы. Отредактировано. Спасибо - person Andrej Ludinovskov; 28.08.2011
comment
Всем большое спасибо, мне очень помогло! - person BoDeX; 28.08.2011
comment
@Andrey: Вы также можете использовать SELECT cars.* FROM ..., так как вы не хотите, чтобы отображались поля из таблицы scores. В конце концов, все они будут NULL. - person ypercubeᵀᴹ; 28.08.2011

person    schedule
comment
Вам действительно нужна таблица user? - person ypercubeᵀᴹ; 28.08.2011