I tried to search posts, but I only found solutions for SQL Server/Access. I need a solution in MySQL (5.X).
I have a table (called history) with 3 columns: hostid, itemname, itemvalue.
If I do a select (select * from history
), it will return
+--------+----------+-----------+
| hostid | itemname | itemvalue |
+--------+----------+-----------+
| 1 | A | 10 |
+--------+----------+-----------+
| 1 | B | 3 |
+--------+----------+-----------+
| 2 | A | 9 |
+--------+----------+-----------+
| 2 | c | 40 |
+--------+----------+-----------+
How do I query the database to return something like
+--------+------+-----+-----+
| hostid | A | B | C |
+--------+------+-----+-----+
| 1 | 10 | 3 | 0 |
+--------+------+-----+-----+
| 2 | 9 | 0 | 40 |
+--------+------+-----+-----+
I figure out one way to make my reports converting rows to columns almost dynamic using simple querys. You can see and test it online here.
The number of columns of query is fixed but the values are dynamic and based on values of rows. You can build it So, I use one query to build the table header and another one to see the values:
You can summarize it, too:
Results of RexTester:
http://rextester.com/ZSWKS28923
For one real example of use, this report bellow show in columns the hours of departures arrivals of boat/bus with a visual schedule. You will see one additional column not used at the last col without confuse the visualization: ** ticketing system to of sell ticket online and presential
I'm going to add a somewhat longer and more detailed explanation of the steps to take to solve this problem. I apologize if it's too long.
I'll start out with the base you've given and use it to define a couple of terms that I'll use for the rest of this post. This will be the base table:
This will be our goal, the pretty pivot table:
Values in the
history.hostid
column will become y-values in the pivot table. Values in thehistory.itemname
column will become x-values (for obvious reasons).When I have to solve the problem of creating a pivot table, I tackle it using a three-step process (with an optional fourth step):
Let's apply these steps to your problem and see what we get:
Step 1: select columns of interest. In the desired result,
hostid
provides the y-values anditemname
provides the x-values.Step 2: extend the base table with extra columns. We typically need one column per x-value. Recall that our x-value column is
itemname
:Note that we didn't change the number of rows -- we just added extra columns. Also note the pattern of
NULL
s -- a row withitemname = "A"
has a non-null value for new columnA
, and null values for the other new columns.Step 3: group and aggregate the extended table. We need to
group by hostid
, since it provides the y-values:(Note that we now have one row per y-value.) Okay, we're almost there! We just need to get rid of those ugly
NULL
s.Step 4: prettify. We're just going to replace any null values with zeroes so the result set is nicer to look at:
And we're done -- we've built a nice, pretty pivot table using MySQL.
Considerations when applying this procedure:
itemvalue
in this exampleNULL
, but it could also be0
or""
, depending on your exact situationsum
, butcount
andmax
are also often used (max
is often used when building one-row "objects" that had been spread across many rows)group by
clause (and don't forget toselect
them)Known limitations:
I make that into
Group By hostId
then it will show only first row with values,like:
use subquery
but it will be a problem if sub query resulting more than a row, use further aggregate function in the subquery
My solution :
It produces the expected results in the submitted case.
I edit Agung Sagita's answer from subquery to join. I'm not sure about how much difference between this 2 way, but just for another reference.