【问题标题】:Postgresql How do I join these tables to get the correct output?Postgresql 如何加入这些表以获得正确的输出?
【发布时间】:2021-06-29 23:29:52
【问题描述】:

我试图找出哪些人被认为是电影中的主要演员,但没有被记录为在该电影中扮演角色。

我的架构是:

CREATE TABLE public.movies (
    id integer NOT NULL,
    title text NOT NULL,
    year_made public.yeartype NOT NULL,
    runtime public.minutes,
    rating double precision,
    nvotes public.counter
);

CREATE TABLE public.people (
    id integer NOT NULL,
    name text NOT NULL,
    year_born public.yeartype,
    year_died public.yeartype
);

CREATE TABLE public.plays (
    movie_id integer NOT NULL,
    person_id integer NOT NULL,
    "character" text NOT NULL
);

CREATE TABLE public.principals (
    movie_id integer NOT NULL,
    ordering public.counter NOT NULL,
    person_id integer NOT NULL,
    role text NOT NULL

到目前为止,我使用的查询适用于某些演员,但是我认为我的连接不正确,因为有另一个演员是主要演员,但被赋予了一个不应该有的角色(角色名称来自他们参演的另一部电影)。这是我的查询:

select name as actor, movies.title as movie,character
from principals
inner join people on principals.person_id=people.id
inner join movies on principals.movie_id=movies.id
left outer join plays on principals.person_id=plays.person_id
where principals.role = 'actor' and character is null

谁能帮我解决这个问题?

这是结果摘要,连接会将所有人物的角色名称添加到他们担任主角的每部电影中。

https://drive.google.com/file/d/1NVRLiYBVbKuiazynx9Egav7c4_VHFEzP/view?usp=sharing

【问题讨论】:

标签: postgresql join null left-join


【解决方案1】:

你已经很接近了,但还需要使用 movie.id 加入戏剧:

select name as actor, movies.title as movie
from principals
join people on principals.person_id=people.id
join movies on principals.movie_id=movies.id
left join plays on principals.person_id=plays.person_id
  and movies.id=principals.movie_id
where principals.role = 'actor'
and character is null

从选择中删除字符,因为它始终为空。

【讨论】:

  • 我尝试了这段代码@Bohmian,但它仍然没有工作。我注意到它会将角色名称添加到他们主要参与的每一部电影(4 次)中。我已经用结果的屏幕截图更新了问题。
  • 数据中的情况比您描述的要多:请显示示例数据。访问sqlfiddle.com 并在那里使用您的架构和数据创建一个小提琴并将链接发布到问题中。
  • 我无法添加到 sqlfiddle,因为数据太大,所以我将它链接到我的谷歌驱动器。
  • 甚至不要尝试添加所有数据。为每个表选择 4-5 行来证明问题。
【解决方案2】:

我认为表plays 需要第二个连接条件,如下图粗体所示:

来自校长 LEFT JOIN 在 principals.person_id = play.person_id 上播放 AND 原则.movi​​e_id = play.movi​​e_id WHERE principals.role = '演员' ANDplays.person_id 为空

但是我觉得not exists 的方法会让这个查询更容易理解:

SELECT
      people.name AS actor
    , movies.title AS movie
    , plays.character
FROM principals
INNER JOIN people ON principals.person_id = people.id
INNER JOIN movies ON principals.movie_id = movies.id
WHERE principals.ROLE = 'actor'
    AND NOT EXISTS (
        SELECT NULL
        FROM plays
        WHERE principals.person_id = plays.person_id
            AND principals.movie_id = plays.movie_id
        )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 2022-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多