Reputation: 539
I have 2 tables - posts and meta
posts structure:
+---------+---------+
| id | title |
+---------+---------+
meta structure:
+---------+---------+---------+
| post | key | value |
+---------+---------+---------+
I need to select records where meta.key is "end" or "result", and goup by post.id (if there's both "end" and "result" meta keys)
Here's my try:
SELECT
posts.id,
posts.title,
meta.post,
meta.`value`,
CASE meta.`key` WHEN 'result' THEN value END AS 'result',
CASE meta.`key` WHEN 'end' THEN value END AS 'end'
FROM
posts
INNER JOIN meta ON posts.id = meta.post
WHERE meta.`key` IN ('result', 'end')
It returns two separate records one with meta.key "end" and one with "result".
+------------+------------+------------+------------+------------+------------+
| id | title | post | value | result | end |
+------------+------------+------------+------------+------------+------------+
| 1 | Untitled | 1 | 5 | (Null) | 1344240000 |
+------------+------------+------------+------------+------------+------------+
| 1 | Untitled | 1 | 88:79 | 88:79 | (Null) |
+------------+------------+------------+------------+------------+------------+
What I need is to merge those two records to one:
+------------+------------+------------+------------+------------+------------+
| id | title | post | value | result | end |
+------------+------------+------------+------------+------------+------------+
| 1 | Untitled | 1 | - | 88:79 | 1344240000 |
+------------+------------+------------+------------+------------+------------+
Upvotes: 3
Views: 725
Reputation: 180887
As long as there's only one row for 'result' and one for 'end' per post id, you can just use MAX
as an aggregate function with your original query and group by posts.id at the end; I can't quite figure out your logic for VALUE
so I left it out for now;
SELECT posts.id, posts.title,
MAX(CASE meta.`key` WHEN 'result' THEN value END) AS 'result',
MAX(CASE meta.`key` WHEN 'end' THEN value END) AS 'end'
FROM posts
INNER JOIN meta ON posts.id = meta.post
WHERE meta.`key` IN ('result', 'end')
GROUP BY posts.id, posts.title
Upvotes: 0
Reputation: 7027
You can do this by INNER JOINing meta twice, i.e.
SELECT
p.id,
p.title,
mr.value AS result,
me.value AS end
FROM posts AS p
INNER JOIN meta AS mr
ON mr.post = p.id
AND mr.`key` = 'result'
INNER JOIN meta AS me
ON me.post = p.id
AND me.`key` = 'end';
SQL fiddle link : http://sqlfiddle.com/#!2/2a89e/5
Upvotes: 1
Reputation: 247650
Since you are trying to pivot the data, you would typically use an aggregate function with the CASE
:
SELECT
posts.id,
posts.title,
-- meta.post,
-- meta.`value`,
max(CASE meta.`key` WHEN 'result' THEN value END) AS 'result',
max(CASE meta.`key` WHEN 'end' THEN value END) AS 'end'
FROM posts
INNER JOIN meta
ON posts.id = meta.post
WHERE meta.`key` IN ('result', 'end')
GROUP BY posts.id, posts.title -- , meta.post, meta.`value`
Note: You are showing two separate values for the value
column, you will need to decide the logic to select a value because if those are distinct when the group by
is performed you will get multiple rows. So you will see that I commented out those two columns since they are being used in the CASE
and the post
column is already displayed.
Upvotes: 0