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
精彩评论