在Postgres中,是否有一种方法可以在由联结表链接的表之间执行left join
,并对链接表进行一些过滤?
说,我有两个表humans
和pets
,我想执行一个查询,该查询中有人类ID和宠物名称。如果存在人类ID,但是他们没有宠物叫该名字,我仍然希望返回人类的行。
如果我有一个从pets
到humans
的FK关系,这将起作用:
select h.*, p.*
from humans as h
left join pets as p on p.human_id = h.id and p.name = 'fluffy'
where h.id = 13
然后我将讨论人类13的详细信息以及蓬松的值。另外,如果人类13没有一个名为“蓬松”的宠物,那么我会得到一行包含人类13的值,并且该宠物列的值为空。
但是,我没有直接的FK关系,我在
humans
和pets
之间有一个联结表,所以我正在尝试一个查询,例如:select h.*, p.*
from humans as h
left join humans_pets_junction as j on j.human_id = h.id
left join pets as p on j.pet_id = p.id and p.name = 'fluffy'
where h.id = 13
它返回所有人类13宠物的行,除了蓬松的行以外,它们的列都是空的。
如果我将
p.name = 'fluffy'
添加到WHERE
子句中,则将所有空行过滤掉,但是这也意味着如果人类13根本没有一只名为蓬松的宠物,我将获得0行。有没有一种方法可以复制FK样式
left join
的行为,但是当与联结表一起使用时? 最佳答案
一种方法是在where
子句中进行比较:
select h.*, p.*
from humans as h left join
humans_pets_junction as j
on j.human_id = h.id left join
pets as p
on j.pet_id = p.id and p.name = 'fluffy'
where h.id = 13 and (p.name = 'fluffy' or p.id is null);
或者,将联结表和pets表作为子查询或CTE连接:
select h.*, p.*
from humans h left join
(select j.*
from humans_pets_junction j join
pets p
on j.pet_id = p.id and p.name = 'fluffy'
) pj
on pj.human_id = h.id
where h.id = 13;