SQL JOIN для внешнего ключа, который не равен первичному ключу - PullRequest
0 голосов
/ 11 января 2019

Я точно не знаю, как правильно сформулировать вопрос, но я в замешательстве. У нас есть тест-экзамен и один из вопросов:

Сортировка актеров по убыванию по количеству фильмов появится в. Показать только имя, фамилию и количество боевики, в которых они играли. которые появились в боевиках, все появились в одном и том же сумма).

Правильный ответ отображается следующим образом:

SELECT 
    Actor.FirstName, Actor.LastName, COUNT(*)
FROM 
    Category 
JOIN 
    Film_Category ON Category.CategoryId = Film_Category.CategoryId
JOIN 
    Film on Film.FilmId = Film_Category.CategoryId
JOIN 
    Film_Actor on Film_Actor.FilmId = Film.FilmId
JOIN 
    Actor ON Actor.ActorId = Film_Actor.ActorId
WHERE 
    Category.Name = 'Action'
GROUP BY 
    Actor.FirstName, Actor.LastName
ORDER BY 
    COUNT(*) DESC

Этот запрос возвращает:

JOHNNY  CAGE    64
ROCK    DUKAKIS 64
CHRISTIAN   GABLE   64
PENELOPE    GUINESS 64
MARY    KEITEL  64
OPRAH   KILMER  64
WARREN  NOLTE   64
SANDRA  PECK    64
MENA    TEMPLE  64
LUCILLE TRACY   64

Строка, которая меня смущает, - это второе СОЕДИНЕНИЕ:

JOIN Film on Film.FilmId = Film_Category.CategoryId

Что делает сравнение Film.FilmId с Film_Category.CategoryId, поскольку это не внешний ключ к этой таблице? Мне даже интересно, если ответ правильный, потому что, когда я ввожу запрос:

SELECT 
    COUNT(Category.Name), Category.Name 
FROM 
    Film_Category 
INNER JOIN 
    Category ON Category.CategoryId = Film_Category.CategoryId 
GROUP BY 
    Category.Name 
ORDER BY 
    COUNT(Category.Name);

Я получаю:

64  Action
66  Animation
68  Documentary

Итак, предположительно, все актеры появились во всех боевиках? Может ли кто-нибудь помочь мне с этим, потому что у меня скоро экзамен, и я проиграл!

Ответы [ 2 ]

0 голосов
/ 11 января 2019

Пусть проверит «ДЖОННИ КЕЙДЖ»

SELECT Actor.FirstName, Actor.LastName, COUNT(*) As AllPlayed
        FROM Film
        JOIN Film_Actor on Film_Actor.FilmId = Film.FilmId
        JOIN Actor ON Actor.ActorId = Film_Actor.ActorId
    Where FirstName ='JOHNNY' And LastName = 'CAGE'
    GROUP BY Actor.FirstName, Actor.LastName

Результат: ДЖОННИ КЕЙДЖ 29

Джонни был в 29 фильмах вообще, ни в 64 боевиках

Тогда ваш запрос неверен, Попробуйте изменить

JOIN Film on Film.FilmId = Film_Category.CategoryId

с

JOIN Film on Film.FilmId = Film_Category.FilmId

....

SELECT Actor.FirstName, Actor.LastName, COUNT(*)
FROM Category JOIN Film_Category ON Category.CategoryId = Film_Category.CategoryId
              JOIN Film on Film.FilmId = Film_Category.FilmId
              JOIN Film_Actor on Film_Actor.FilmId = Film.FilmId
              JOIN Actor ON Actor.ActorId = Film_Actor.ActorId
WHERE Category.Name = 'Action'
GROUP BY Actor.FirstName, Actor.LastName
ORDER BY COUNT(*) DESC
0 голосов
/ 11 января 2019

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

SELECT a.FirstName, a.LastName, COUNT(*)
FROM Category c JOIN
     Film_Category fc
     ON c.CategoryId = fc.CategoryId JOIN
     Film_Actor fa
     ON fa.FilmId = fc.FilmId JOIn
     Actor a
     ON a.ActorId = fa.ActorId
WHERE c.Name = 'Action'
GROUP BY a.FirstName, a.LastName
ORDER BY COUNT(*) DESC;

Обратите внимание, что таблица Film не нужна. Тем не менее, я думаю, что ответ на вопрос:

SELECT a.FirstName, a.LastName,
       SUM(CASE WHEN c.Name = 'Action' THEN 1 ELSE 0 END) as num_action
FROM Category c JOIN
     Film_Category fc
     ON c.CategoryId = fc.CategoryId JOIN
     Film_Actor fa
     ON fa.FilmId = fc.FilmId JOIn
     Actor a
     ON a.ActorId = fa.ActorId
GROUP BY a.FirstName, a.LastName
ORDER BY COUNT(*) DESC;

Вопрос говорит о том, что нужно заказывать все фильмы, но показывать только количество боевых фильмов.

...