简体   繁体   中英

SQL rows from multiple tables

I have a table which represents a list

id  |  item_type  |  item_id
----------------------------
1      'article'     24
2      'post'        9
3      'article'     120
4      'image'       9

item_type basically represent from which table the row is suppose to be and id is the id from that table. Which means that for example second and fourth line are not the same.

I would like to get lets say item_title and more columns which are going to be created differently based on each table.
Lets say if item_type = 'article', then item_title = title from that table.
But if item_type is 'image' item_title = author_first_name + author_second_name + image_id
etc...

I was googling it or how to approach it. Particularly I thought I could be solved by sql if statement with subqueries but so far was unable to make a real progress. So I would like to ask for help or point out the right direction.

Although the accepted answer is accurate and relatively concise, it is also laborious. (The article table is being joined to post and image rows, even though the results are then discarded.)

To improve that you could start with...

select
    i.*,
    case 
      when i.item_type = 'article' then a.title
      when i.item_type = 'post'    then p.post_title
      when i.item_type = 'image'   then g.author_first_name + g.author_second_name + g.image_id
    end as item_title
  from item i
  left join article a on i.item_id = a.id AND i.item_type = 'article'
  left join post    p on i.item_id = p.id AND i.item_type = 'post'
  left join image   g on i.item_id = g.id AND i.item_type = 'image'

Many optimisers don't actually like that though. If you really want to get the most out of your database, I would put an index on item(item_type) and then use explicit logic for each type...

   SELECT i.*, a.title
     FROM item i
LEFT JOIN article a ON i.item_id = a.id
    WHERE i.item_type = 'acticle'

UNION ALL

   SELECT i.*, p.post_title
     FROM item i
LEFT JOIN post p ON i.item_id = p.id
    WHERE i.item_type = 'post'

UNION ALL

   SELECT i.*, g.author_first_name + g.author_second_name + g.image_id
     FROM item i
LEFT JOIN image g ON i.item_id = g.id
    WHERE i.item_type = 'image'

More long winded, but much more explicit and optimiser friendly.

You can perform OUTER JOIN s to all those tables and compose a title using the appropriate columns, as in:

select
    i.*,
    case 
      when i.item_type = 'article' then a.title
      when i.item_type = 'post'    then p.post_title
      when i.item_type = 'image'   then
        g.author_first_name + g.author_second_name + g.image_id
    end as item_title
  from item i
  left join article a on i.item_id = a.id
  left join post    p on i.item_id = p.id
  left join image   g on i.item_id = g.id

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM