不等于主键的外键上的SQL JOIN

时间:2019-01-10 23:19:27

标签: sql join foreign-keys sql-server-2017

我不完全知道如何正确地表达问题,但我完全感到困惑。我们有一个考试,问题之一是:

  

根据演员的电影数量排序演员降序   出现在。仅显示名字,姓氏和金额   他们参加过的动作电影。(注:不幸的是,所有演员   在动作电影中出现过的影片都以相同的形式出现   金额)。

正确答案显示如下:

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:

JOIN Film on Film.FilmId = Film_Category.CategoryId

比较Film.FilmIdFilm_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 :(得分:2)

查询不正确。根据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;

问题是说要按所有电影排序,但只显示 action 电影的计数。

答案 1 :(得分:1)

让我们检查“约翰尼·凯奇”(JOHNNY CAGE)

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