Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Conditional / Case Joining / Polymorphic Associations?

I'm trying to implement something similar to Ruby on Rails' polymorphic relationships. I have the following three tables :

Events Users Organisations

An event can be owner by either a user or an organisation, so my Events table includes the columns: owner_type and owner_id.

I can easily list all events that belong to either users or organisations through an inner join and where clause, however, is there a way to make the join table conditional based on the value of the owner_type column, allowing all events to be listed together, regardless of owner_type?

I hope that makes sense.

Any advice appreciated.

Thanks.

like image 828
Dan Avatar asked Feb 25 '10 11:02

Dan


2 Answers

You can't make the join table conditional, so in this case you would have to join events to both users and organisations and use coalesce to merge the common fields (eg. name) together.

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'

However, you may consider creating an owners table, which contains both users and organisations, with a structure like (id, type, org_id, name, ...). This would only require a single join, but may complicate other areas of your schema, eg. user membership of an organisation.

An alternative method would be to union the users and organisations tables together and then join once from events.

like image 74
a'r Avatar answered Sep 21 '22 17:09

a'r


eventowner_model_01



  • Owner has columns common to all owner-subtypes.
  • Person and Organization have columns specific to each one.
like image 36
Damir Sudarevic Avatar answered Sep 25 '22 17:09

Damir Sudarevic