尝试不正确:PostgreSQL中使用“不存在/不存在”的关系划分

时间:2019-03-27 21:44:39

标签: sql postgresql

说明:根据DVD Rental示例数据库中的film_actorfilm表,可以找到Sidney Crowe (actor_id = 105)和Salma Nolte (actor_id = 122)一起放映的所有电影,并对结果进行排序按字母顺序设置。

  

电影模式

Column     | Type                        | Modifiers
------------+-----------------------------+----------
title       | character varying(255)      | not null
film_id     | smallint                    | not null
  

电影演员模式

Column     | Type                        | Modifiers
------------+-----------------------------+----------
actor_id    | smallint                    | not null
film_id     | smallint                    | not null
last_update | timestamp without time zone | not null 
  

演员模式

Column     | Type                        | Modifiers
------------+-----------------------------+----------
actor_id    | integer                     | not null 
first_name  | character varying(45)       | not null
last_name   | character varying(45)       | not null
last_update | timestamp without time zone | not null 
  

所需的输出

title
-------------
Film Title 1
Film Title 2
...

我的错误尝试:

select f.title
from Film F inner join 
     film_actor FA on F.film_id = FA.film_id
where not exists (select film_id from film as F 
                  where actor_id = '105') 
                    and f.film_id not in (select film_id from 
                    film as F2 where FA.actor_id = '122') 

我上面的查询背后的逻辑(显然不正确): 我想创建一个表格,其中包含Sidney Crowe (actor_id = 105)主演的所有电影及其电影ID。现在将对这些电影进行逐一测试:要使Sidney Crowe主演的电影成为结果的一部分,该电影的不存在子句必须为真(这意味着不存在之后的列表必须为空)

where子句的子查询的第二部分中,将上述内容(Sidney乌鸦出演的电影)与Salma Nolte(actor_id = 122)所在的电影逐一进行测试。< / p>

我的结果不正确,我想知道我在哪里搞砸了,或者有人可以向我解释那真是太好了!谢谢你!

1 个答案:

答案 0 :(得分:0)

您可以两次使用EXISTS

select f.*
from Film f 
where 
  exists (
    select 1 from Film_Actor 
    where film_id = f.film_id and actor_id = 105
  )
  and
  exists (
    select 1 from Film_Actor 
    where film_id = f.film_id and actor_id = 122
  )
order by f.title

或先将Film_Actor表分组,然后再加入Film表:

select f.* from Film f inner join ( 
  select film_id 
  from Film_Actor
  where actor_id in (105, 122)
  group by film_id
  having count(actor_id) = 2
) g on g.film_id = f.film_id
order by f.title