5

我正在尝试实现类似于 Ruby on Rails 的多态关系的东西。我有以下三个表:

活动用户组织

事件可以由用户或组织拥有,因此我的事件表包括以下列:owner_type 和 owner_id。

我可以通过内部连接和 where 子句轻松列出属于用户或组织的所有事件,但是,有没有办法根据 owner_type 列的值使连接表有条件,从而允许将所有事件一起列出,无论所有者类型如何?

我希望这是有道理的。

任何建议表示赞赏。

谢谢。

4

4 回答 4

7

您不能使连接表有条件,因此在这种情况下,您必须将事件连接到用户和组织,并使用合并将公共字段(例如名称)合并在一起。

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, ...)。这只需要一个连接,但可能会使您的架构的其他区域复杂化,例如。组织的用户成员资格。

另一种方法是将用户和组织表联合在一起,然后从事件中加入一次。

于 2010-02-25T11:21:09.363 回答
2

eventowner_model_01



  • Owner具有所有所有者子类型共有的列。
  • PersonOrganization具有特定于每个的列。
于 2010-02-25T11:26:40.633 回答
0

如何将所有权信息移出Events两个连接表,EventsUsers并且EventsOrganisations(每个只有两列,FKEvents和相应的拥有对象表)?然后,您可以进行UNION两个查询,每个查询都通过连接表连接到拥有对象表。

于 2010-02-25T11:21:36.893 回答
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

于 2021-02-10T19:22:58.763 回答