我正在尝试实现类似于Ruby on Rails的多态关系。 我有以下三个表:
活动 用户 组织
事件可以是用户或组织的所有者,因此我的事件表包括列:owner_type和owner_id。
我可以通过内部联接和where子句轻松列出属于用户或组织的所有事件,但是,有没有办法根据owner_type列的值使连接表成为条件,允许所有事件都是列在一起,不管owner_type?
我希望这是有道理的。
任何建议表示赞赏。
感谢。
答案 0 :(得分:4)
您不能使连接表成为条件,因此在这种情况下,您必须将事件连接到用户和组织,并使用coalesce将公共字段(例如名称)合并在一起。
select e.id, coalesce(u.name, o.name) owner_name
from events e
left join users u on e.owner_id = u.id and e.owner_type = 'user'
left join organisations o on e.owner_id = o.id and e.owner_type = 'org'
但是,您可以考虑创建一个包含用户和组织的所有者表,其结构类似于(id,type,org_id,name,...)。这只需要一次连接,但可能会使架构的其他区域复杂化,例如。组织的用户成员资格。
另一种方法是将用户和组织表联合在一起,然后从事件中加入一次。
答案 1 :(得分:2)
答案 2 :(得分:0)
如何将所有权信息从Events
移出到两个连接表EventsUsers
和EventsOrganisations
(每个连接表只有两列,FK到Events
和适当的拥有对象表)?然后你可以UNION
两个查询,每个查询通过连接表连接到拥有对象表。
答案 3 :(得分:0)
有点旧,但我认为它会很有用,这个版本在我的场景中比多连接表现更好
select e.id,
case when e.owner_type = 'person' then
(
select p.name from person p
where p.id=e.owner_id
)
else
(
select o.name from organization o
where o.id=e.owner_id
)
end entityName,
e.owner_type
from events e
在 postgres 中你甚至可以构建一个包含整个相关实体的 json