-2

我想知道每一位导演过 20 多部电影并参与过他导演的每一部电影的男导演的名字。如果他演了一部电影,但没有导演,那没关系,我仍然想要他的名字;如果他导演了任何电影但没有出演,我不再想要他了。

SELECT p.firstname, 
    p.lastname 
FROM person p 
WHERE p.gender = 'M' AND
(
    SELECT COUNT(*)
    FROM filmparticipation fpd 
    WHERE p.personid = fpd.personid AND
        fpd.parttype = 'director' AND
        (
            SELECT COUNT(*) 
            FROM filmparticipation c 
            WHERE c.personid = fpd.personid AND
                c.filmid = fpd.filmid AND
                c.parttype = 'cast'
        ) > 0
) >= 20;

这只是我的多次尝试之一。作为一个附带问题,为什么它不起作用?我确保我正在检查正确的导演电影 ID 到演员电影 ID 等。

4

1 回答 1

1

可能看起来像这样:

SELECT p.firstname, p.lastname 
FROM   person p
JOIN  (
   SELECT fd.personid
   FROM   filmparticipation fd
   LEFT   JOIN filmparticipation fc USING (personid, filmid)
   WHERE  fd.parttype = 'director'
   AND    fc.parttype = 'cast'
   GROUP  BY fd.personid
   HAVING count(*) > 20  -- 21+ movies directed (NULL not counted)
   AND    NOT bool_or(fc.personid IS NULL) -- no movie directed but not cast
   ) AS fp USING (personid)
WHERE  p.gender = 'M';

在子查询中,我LEFT [OUTER] JOIN在同一部电影的同一个人导演和演员的所有行中 - 他只导演了其余的地方NULL。这就是 a 的LEFT JOIN作用。这假设同一个人只能在同一部电影中以同一角色出现一次(UNIQUE 或 PK 约束!)。

Grouping bypersonid必须导致超过 20 行,并且没有一个转换personid可以是NULL. JOIN到 person 表并限制为男性,你就完成了。

有很多方法可以解决它,应该是最快的一种。

于 2012-10-31T20:58:27.330 回答