Im using a HSLQDB (2.2.9) database which I connect to via java JDBC.
Person A has received vaccinations 1 and 3, person B has received 2 and 4.
Using this simple query:
SELECT std.*,vac.Date FROM Students AS std
LEFT JOIN ValuesVaccination AS vac
ON vac.ID_Students = std.ID
I get a result set like:
ID | Name | ID_Vaccination | Date
1 | PersonA | 1 | 2011-06-01
1 | PersonA | 3 | 2012-03-21
1 | PersonB | 2 | 2012-08-11
2 | PersonB | 4 | 2012-09-08
What I want to get is:
ID | Name | Vaccination1 | Vaccination2 | Vaccination3 | Vaccination4
1 | PersonA | 2011-06-01 | NULL | 2012-03-21 | NULL
2 | PersonB | NULL | 2012-08-11 | NULL | 2012-09-08
One way to do this is:
SELECT std.*,
vac1.Date AS "Vaccination1",
vac2.Date AS "Vaccination2",
vac3.Date AS "Vaccination3",
vac4.Date AS "Vaccination4"
FROM Students AS std
LEFT JOIN ValuesVaccination AS vac1
ON vac1.ID_Students = std.ID AND vac1.ID_Vaccinations = 1
LEFT JOIN ValuesVaccination AS vac2
ON vac2.ID_Students = std.ID AND vac2.ID_Vaccinations = 2
LEFT JOIN ValuesVaccination AS vac3
ON vac3.ID_Students = std.ID AND vac3.ID_Vaccinations = 3
LEFT JOIN ValuesVaccination AS vac4
ON vac4.ID_Students = std.ID AND vac4.ID_Vaccinations = 4
The problem is the number of different vaccinations is variable. Is there a decent way to do this without building the query with the JOINs in a java String using a loop?
I figured out the PIVOT function is what I need, but it seems HSQLDB does not support it and searching stackoverflow and google did not bring up useful information.
Thank you for any information
PIVOTis not standard SQL, it’s an extension to syntax supported only by Microsoft SQL Server 2005 (and later), and Oracle 11g.Here’s a solution that uses standard SQL and should work in any RDBMS:
Re your comment:
SQL does not allow data values to generate new columns dynamically in the same query. So
any pivot query requires that you know how many distinct vaccinations you want to show in the output before you prepare the query.
You could run two queries: one to “discover” the set of distinct vaccination values:
Then fetch that back into the application and loop over it, adding column expressions as you go, to build the pivot query.
The only alternative is to fetch all the data joined to Students, as in your first query, and post-process it into a pivoted format using application code.
Either way, to produce a dynamic pivot query you have to supplement it with application code, either before you prepare the query or after you fetch the results.