Как я могу создать запрос MySQL JOIN только для выбора строк в одной таблице, где определенное количество ссылок на эту строку существует в другой таблице? - PullRequest
3 голосов
/ 06 октября 2008

У меня есть две таблицы в моей базе данных, которые называются рейтинги и фильмы .

Оценка:

| id | movie_id | rating |

Фильмы:

| id | title |

Типичная запись фильма может быть такой:

| 4 | Cloverfield (2008) |

и для Cloverfield может быть несколько рейтинговых записей, например:

| 21 | 4 | 3 | (рейтинг № 21, в фильме № 4, присвоив ему рейтинг 3)

| 22 | 4 | 2 | (рейтинг № 22, в фильме № 4, присвоив ему рейтинг 2)

| 23 | 4 | 5 | (рейтинг № 23k в фильме № 4 с рейтингом 5)

Вопрос:

Как создать запрос JOIN для выбора только тех строк в таблице фильмов, которые имеют более чем x оценок в таблице оценок? Например, в приведенном выше примере, если у Cloverfield был только один рейтинг в таблице рейтингов, а x равнялся 2, он не был бы выбран.

Спасибо за любую помощь или совет!

Ответы [ 5 ]

7 голосов
/ 06 октября 2008

Используйте предложение HAVING. Что-то вроде этого:

SELECT movies.id, movies.title, COUNT(ratings.id) AS num_ratings 
  FROM movies 
  LEFT JOIN ratings ON ratings.movie_id=movies.id 
  GROUP BY movies.id 
  HAVING num_ratings > 5;
3 голосов
/ 06 октября 2008

Возможно, вы захотите использовать предложение HAVING в MySQL

http://www.severnsolutions.co.uk/twblog/archive/2004/10/03/havingmysql

2 голосов
/ 06 октября 2008

Метод JOIN несколько неестественен и запутан, потому что это не совсем то, для чего он предназначен. Самый прямой (и, на мой взгляд, легко разбираемый человеком) метод использует EXISTS:

SELECT whatever
  FROM movies m
 WHERE EXISTS( SELECT COUNT(*) 
                 FROM reviews
                WHERE movie_id  = m.id
               HAVING COUNT(*)  > xxxxxxxx )

Прочтите это вслух - ВЫБЕРИТЕ что-нибудь из фильмов, ГДЕ существуют строки в Отзывы, где совпадает идентификатор фильма и есть> строки xxxxxx

1 голос
/ 06 октября 2008
SELECT * FROM movies 
INNER JOIN
(SELECT movie_id, COUNT(*) as num_ratings from ratings GROUP BY movie_id) as movie_counts
ON movies.id = movie_counts.movie_id
WHERE num_ratings > 3;

Это даст вам только фильмы с более чем 3-мя рейтингами, а чтобы получить рейтинги, потребуется еще одно объединение. Преимущество подзапроса перед HAVING заключается в том, что вы можете агрегировать рейтинги одновременно. Такие как (ВЫБРАТЬ идентификатор фильма, СЧЕТЧИК (*), AVG (рейтинг) как среднее значение_объявления ...)

Редактировать: К сожалению, вы можете объединить с имеющим метод для. :)

0 голосов
/ 06 октября 2008

Вышеуказанные решения подходят для сценария, который вы упомянули. Мое предложение может быть излишним для того, что вы имеете в виду, но может быть полезно для других ситуаций:

  1. Подзапрашивать только те из таблицы рейтингов, которые содержат больше нужного вам числа (снова используя группу с предложением):

    выберите movie_id из группы рейтингов по movie_id с количеством (*)> x

  2. Присоединиться к этому подзапросу с таблицей фильмов

    выберите movies.id из фильмов присоединяйся as MoviesWRatings на movies.id = MoviesWRatings.movie_id

Когда вы делаете больше вещей для подзапроса, это может быть полезно. (Не уверен, что синтаксис правильный для MySQL, исправьте, если необходимо.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...