SQL条件/案例连接/多态关联?

时间:2010-02-25 11:13:27

标签: sql polymorphic-associations

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

活动 用户 组织

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

我可以通过内部联接和where子句轻松列出属于用户或组织的所有事件,但是,有没有办法根据owner_type列的值使连接表成为条件,允许所有事件都是列在一起,不管owner_type?

我希望这是有道理的。

任何建议表示赞赏。

感谢。

4 个答案:

答案 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)

eventowner_model_01



  • Owner包含所有所有者 - 子类型共有的列。
  • PersonOrganization包含特定于每个列的列。

答案 2 :(得分:0)

如何将所有权信息从Events移出到两个连接表EventsUsersEventsOrganisations(每个连接表只有两列,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