我在PostgreSQL 9.2.24数据库中有一个表:
CREATE TABLE episodes_list (
mid serial PRIMARY KEY -- movie id
, title text NOT NULL
, is_movie integer NOT NULL -- 1 for movie, 0 for episode
);
我需要在剧集的左标题上显示所有电影(甚至没有剧集的电影)的右标题上。
103 | Microcosmos (high quality) | 1
103 | Snails' sexual act | 0
103 | Landing | 0
以下是一些记录。因此,例如。 “ Microcosmos”应在右侧两次,蜗牛的性行为应降落在左侧。那应该是这样的:
Landing | Microcosmos (high quality)
Snails' sexual act | Microcosmos (high quality)
我写了这样的东西:
select e1.title, e2.title from episodes_list e1 right join episodes_list e2 on e1.is_movie = 0 and e2.is_movie = 1 and e1.mid = e2.mid;
但是它仍然显示在剧集的正确标题上,而不是仅显示电影标题(因此,我得到了我不应该获得的其他内容)。所以看起来像这样: 但它看起来像这样:
Landing | Microcosmos (high quality)
Snails' sexual act | Microcosmos (high quality)
| Snails' sexual act
我在这里做错了什么,查询应该是什么样子?
答案 0 :(得分:2)
这可能是您的查询
SELECT epi.title AS episode, mov.title AS movie
FROM episodes_list epi
RIGHT JOIN episodes_list mov ON epi.is_movie = 0
AND mov.mid = epi.mid
WHERE mov.is_movie = 1;
这将向右返回所有电影,并在可用的情况下向左扩展情节。
is_movie
实际上应该是boolean
标志。 integer
不是正确的类型。
最重要的一点是:格式化查询(以任何一致的方式,不一定像我的那样),并在情况复杂时使用描述性别名。
您遇到的逻辑问题:WHERE
子句中的条件等同于INNER JOIN
子句中的条件,但不等同于OUTER JOIN
中的条件。 ({LEFT JOIN
/ RIGHT JOIN
代表LEFT OUTER JOIN
/ RIGHT OUTER JOIN
的缩写。)
参见:
答案 1 :(得分:1)
您需要在表上选择一个自我LEFT JOIN来选择剧集记录,并带有一个WHERE子句,该子句仅对电影进行过滤。
以下查询应完成工作:
select
e2.title,
e1.title
from episodes_list e1
left join episodes_list e2
on e2.is_movie = 0
and e1.mid = e2.mid
where e1.is_movie = 1
e1代表电影记录。 e2代表情节记录。左联接可以将没有剧集的电影考虑在内。