There’s a following table, called fields
:
And there’s a dedicated table to store its values, called values
I want to run a query to produce the following output:
Finished | Faculity | Characteristic | Photo
---------------------------------------------
1 | Math | Good |
0 | Biology | Not Good |
I want to build a query that outputs aformentioned result. But it’s not that easy as it seems. From this simlar question, I have tried running the following query:
SELECT flds.id,
(case when flds.name = 'Finished' THEN vals.value END) AS Finished,
(case when flds.name = 'Faculty' THEN vals.value END) AS Faculty,
(case when flds.name = 'Characteristic' THEN vals.value END) AS Characteristic,
(case when flds.name = 'Photo' THEN vals.value END) AS Photo
FROM `values` vals
LEFT JOIN `fields` flds
ON vals.field_id = flds.id
GROUP BY
flds.id,
vals.value;
Which gives me an unexpected result:
Is there any way to resolve it?
2
Answers
Assuming that there is equal number of rows in
field_values
for each id infields
. That is to say that this query returns a1
:Otherwise, the solution will require a bunch of FULL JOINS and it will get messy. Especially since MySQL doesn’t have a FULL JOIN, so you’d have to UNION ALL a LEFT/RIGHT ANTI JOIN with a RIGHT/LEFT JOIN (respectively).
Create the tables an populate with your sample data
JOIN fields with field_values, keeping track of the order of the id from field_values. As I am also assuming that you want to use this value to determine the final display order.
JOIN this result with itself for as many columns as you want in your final result, matching on the appropriate ordinal position.
Try it yourself: db<>fiddle
count the number of field values prior to the current id then group by and aggregate
eg