I try to create a procedure that transforms the following table from:
ID | Visit | Date |
---|---|---|
1234567 | Cake | 01.01.2023 |
1234567 | Coffee | 01.01.2023 |
1234567 | Cake | 02.01.2023 |
2345678 | Coffee | 02.02.2023 |
2345678 | Coffee | 03.02.2023 |
to:
ID | Cake | Coffee |
---|---|---|
1234567 | Max(Date) 02.01.2023 | Max(Date) 01.01.2023 |
2345678 | Max(Date) None | Max(Date) 03.02.2023 |
The number of different items in column Visit (and all other columns) can change dynamically.
I noticed that mysql does not support pivot, and based on what I found on the internet, I tried the following.
Unfortunately, I don’t even get this code to run. Do you have any ideas on what I can improve?
Thank you for your support!!! Thats so much appreciated!!
Best,
Janine
Code:
CREATE PROCEDURE VisitReport.Pivot()
BEGIN
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT CONCAT(
'MAX(CASE WHEN Visit= "', Visit, '" THEN [Date] ELSE 0 END)
AS ', Visit, '"')
)
INTO @sql
FROM VisitReport;
SET @sql = CONCAT('SELECT ID, ', @sql,
' FROM VisitReport GROUP BY ID');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
2
Answers
You can try the following:
to call the procedure:
I am just assuming that there will be none other than
cake
andcoffee
.Let me know if I am missing something
Given that information, this is impossible to do in a single SQL statement.
The SQL language has a very strict rule that the number and types of columns must be known at query compile time, before looking at any data. Since you have to look at the data to know what columns to show, you will not be able to do this in a single SQL query.
Instead, you must use dynamic SQL do this over three steps:
It’s also worth noting that adding
PIVOT
support would not help. Even with PIVOT, you still need to know that number of result columns.That said, you’d made good progress towards this result. Once we know the columns, PIVOT might improve this query, but without it the conditional aggregation strategy already attempted is our best bet. I only needed to clean up a few syntax issues with using single quotes instead of double and back-ticks instead of square-brackets. I took the liberty of improving the format of the result as well, which helps with debugging:
See it here:
The fiddle just copy/pastes the result from the 2nd sample block to the third to give the correct result.