Как мне написать предложение JOIN, чтобы оно работало хорошо? - PullRequest
1 голос
/ 23 июня 2019

Я делаю Q4 (найдите названия всех фильмов, которые не были просмотрены Крисом Джексоном.) Из дополнения SQL Query-Rating Query Exercises, и я не знаю, почему этот код не работает:

SELECT DISTINCT movie.title
FROM movie
        INNER JOIN rating ON movie.mid = rating.mID
        INNER JOIN reviewer ON rating.rid = reviewer.rid
WHERE rating.mid NOT IN (SELECT rating.mid FROM rating WHERE rating.rid = (SELECT reviewer.rid FROM reviewer WHERE reviewer.name = 'Chris Jackson') )

Вывод:

title
Gone with the Wind
Snow White
Avatar

Этот вывод не включает фильмы, которые находятся в таблице фильмов, но НЕ находятся в таблице рейтинга.Поэтому я подозреваю, что, возможно, это как-то связано с предложением JOIN.

ТАБЛИЦЫ:Фильм

mID title                   year    director
101 Gone with the Wind      1939    Victor Fleming
102 Star Wars               1977    George Lucas
103 The Sound of Music      1965    Robert Wise
104 E.T.                    1982    Steven Spielberg
105 Titanic                 1997    James Cameron
106 Snow White              1937    <null>
107 Avatar                  2009    James Cameron
108 Raiders of the Lost Ark 1981    Steven Spielberg

Рецензент

rID name
201 Sarah Martinez
202 Daniel Lewis
203 Brittany Harris
204 Mike Anderson
205 Chris Jackson
206 Elizabeth Thomas
207 James Cameron
208 Ashley White

Рейтинг

rID mID stars   ratingDate
201 101 2       2011-01-22
201 101 4       2011-01-27
202 106 4       <null>
203 103 2       2011-01-20
203 108 4       2011-01-12
203 108 2       2011-01-30
204 101 3       2011-01-09
205 103 3       2011-01-27
205 104 2       2011-01-22
205 108 4       <null>
206 107 3       2011-01-15
206 106 5       2011-01-19
207 107 5       2011-01-20
208 104 3       2011-01-02

Ответы [ 2 ]

1 голос
/ 23 июня 2019

Сначала вы должны использовать LEFT JOIN, а затем затем использовать GROUP BY movie.mid, movie.title и поместить условие в предложение HAVING:

SELECT movie.title
FROM movie
LEFT JOIN rating ON movie.mid = rating.mID
LEFT JOIN reviewer ON rating.rid = reviewer.rid
GROUP BY movie.mid, movie.title
HAVING SUM(CASE WHEN reviewer.name = 'Chris Jackson' THEN 1 ELSE 0 END) = 0

См. Демоверсию .
Результаты:

> | title              |
> | :----------------- |
> | Avatar             |
> | Gone with the Wind |
> | Snow White         |
> | Star Wars          |
> | Titanic            |
0 голосов
/ 23 июня 2019

Хотя вы можете использовать агрегацию, я бы порекомендовал NOT EXISTS для этой цели.Это близко к формулировке логики, которую вы хотите:

SELECT m.*
FROM movie m
WHERE NOT EXISTS (SELECT 1
                  FROM rating r JOIN
                       reviewer re
                       ON r.rid = re.rid
                  WHERE m.mid = r.mID AND
                        re.name = 'Chris Jackson'
                 );

Не должно быть никакого сравнения с точки зрения производительности.Это должно иметь гораздо лучшую производительность.

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