什么是检索以下结果集的最佳SQL查询

amn*_*amn 5 sql optimization

我会提前说,出于对你的时间和网站的尊重 - 这一项家庭作业.但是,我已经考虑并编写了一个解决方案,但由于我无法成功地对其进行分析或在其他地方获得相关的第三方意见,以确定它是否实际上是一个好的事实,我有点恼火.

假设我有一个简单的电影参与信息表(人物,电影,人物与电影的关系)如下:

create table film
(
    person_name varchar(48) not null,
    film_title varchar(128) not null,
    relation varchar(48) not null
);

-- { 'Mel Gibson', 'Braveheart', 'director' }
-- { 'Mel Gibson', 'Braveheart', 'cast' }
-- { 'Steven Spielberg', 'A.I.' , 'director' }
-- { 'Hilary Swank', 'Million Dollar Baby', 'cast' }
-- etc
Run Code Online (Sandbox Code Playgroud)

数据库和表格不是由我创建或维护的,我只是从中查询信息.

我需要为他们指导的部电影中的演员(在镜头前行动)制作一套人名.该条件应持有谁曾执导最少一部电影中,他们不采取行动,或谁没有任何指示的人的人.

我的查询(据我可以证明,产生了正确的结果集),瞧瞧:

(   
    select  person_name 
    from    film 
    where   relation = 'director'
)
except 
(
    select person_name
    from 
    (   
        (
            select  person_name, film_title 
            from    film 
            where   relation = 'director'
        ) 
        except 
        (   
            select  person_name, film_title 
            from    film 
            where   relation = 'cast'
        )
    ) as director_behind_camera_for_film
)
Run Code Online (Sandbox Code Playgroud)

我想知道查询是否合理,或者我是否一直在想这个问题?如果是后者,请您提供更好的解决方案或解释吗?

不要太注意我到处使用字符串的事实(代理键可能已经被用过了) - 这是一个简化的例子,但它仍然证明了我的挑战.

fra*_*ail 4

SELECT tmp.person_name FROM
(
   SELECT person_name, film_title, COUNT(relationship) as cnt
   FROM film
   WHERE relationship IN ('cast', 'director')
   GROUP BY person_name, film_title
) as tmp
GROUP BY person_name
HAVING SUM(cnt) = COUNT(cnt)*2
Run Code Online (Sandbox Code Playgroud)

或者

SELECT tmp.person_name FROM
(
   SELECT person_name, film_title, COUNT(DISTINCT(relationship)) as cnt
   FROM film
   WHERE relationship IN ('cast', 'director')
   GROUP BY person_name, film_title
) as tmp
GROUP BY person_name
HAVING SUM(cnt) = COUNT(cnt)*2
Run Code Online (Sandbox Code Playgroud)