开发者

Mysql Select 1:n

I have two tables that relates 1:n

content
---------
- id
- title
- text

content_meta
-------------
- id
- content_id
- meta_key
- meta_value

A content can have multiple content_meta registers associated to it. Typically content_meta will contain the category, tags, descriptions and all that stuff, so I really don't know the number of registers a content will have.

What I want to accomplish is to take the content register and also all the related registers in content_meta in a single query. I've tried the subselect approachment but seems that I can only get one register/column (¿?) SELECT content.*, ( SELECT * FROM content_meta WHERE content_id = content.id ) FROM content

This query co开发者_JAVA技巧mplains that "Operand should contain 1 column(s)", so changing the '*' by for example meta_key clears the error, but returns a NULL for this subselect...

SELECT content.*, (
                  SELECT meta_key
                  FROM content_meta
                  WHERE content_id = content.id
                 )
 FROM content

Can anybody show me where to go from here please?


Use:

SELECT c.*,
       cm.*
  FROM CONTENT c
  JOIN CONTENT_META cm ON cm.content_id = c.id

That will only return CONTENT and related when there is a supporting record in the CONTENT_META table. If it's possible for a CONTENT record to not have any CONTENT_META data, use a LEFT JOIN instead:

   SELECT c.*,
          cm.* --these columns will be null if there is no supporting data
     FROM CONTENT c
LEFT JOIN CONTENT_META cm ON cm.content_id = c.id

Followup Question -


it is now possible to group by content.id, but renaming the meta_key column with its own value and the value of this column the content of meta_value?

MySQL doesn't have PIVOT syntax - you have to use CASE statements:

  SELECT c.id,
         MAX(CASE WHEN cm.meta_key = 'A' THEN cm.meta_value ELSE NULL END) AS 'A',
         MAX(CASE WHEN cm.meta_key = 'B' THEN cm.meta_value ELSE NULL END) AS 'B',
         MAX(CASE WHEN cm.meta_key = 'C' THEN cm.meta_value ELSE NULL END) AS 'C'
    FROM CONTENT c
    JOIN CONTENT_META cm ON cm.content_id = c.id
GROUP BY c.id

You'll have to specify the meta_key for each one you want to appear in the resultset.


How about just doing a join on the content id column?


SELECT * FROM content
LEFT JOIN content_meta ON content.id = content_meta.content_id
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜