【问题标题】:Incorrect attempt: Relational Division in PostgreSQL using Not Exist/Not In不正确的尝试:PostgreSQL 中的关系除法使用 Not Exist/Not In
【发布时间】:2019-03-27 21:44:38
【问题描述】:

说明:给定 DVD 租赁示例数据库中的 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

Film_Actor 架构

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。现在将对这些影片一一进行测试:要使西德尼·克劳主演的影片成为结果的一部分,这部电影的不存在子句必须为真(即不存在后的列表必须为空)

where 子句的子查询的第二部分,然后将上述(Sidney crow 出演的电影)与 Salma Nolte (actor_id = 122) 出演的电影一一进行测试。

我的结果不正确,我想知道我在哪里搞砸了,或者是否有人可以向我解释逻辑,这将是惊人的谢谢!

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    你可以使用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
    

    【讨论】:

    • 您能解释一下“从 Film_Actor 中选择 1”的作用吗?是选择一部电影吗?非常感谢!
    • Exists 如果至少存在 1 行满足film_id = f.film_id and actor_id = 105 的条件,则返回 true。 select 1 没有特殊含义,它可以是 select * 或 select 0。唯一重要的是存在后的查询返回至少 1 行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多