You could use this query:
SELECT
regdate,
SEC_TO_TIME(TRUNCATE(TIME_TO_SEC(regtime)/(60*30),0)*(60*30)) reginterval,
COUNT(CASE WHEN items='item1' THEN 1 END) item1,
COUNT(CASE WHEN items='item2' THEN 1 END) item2,
COUNT(CASE WHEN items='item3' THEN 1 END) item3,
COUNT(CASE WHEN items='item4' THEN 1 END) item4
FROM Data
GROUP BY
regdate,
reginterval
If you need to insert the resulting rows into a new table, just add this line at the beginning:
INSERT INTO ItemsPerInterval (regdate, reginterval, item1, item2, item3, item4)
SELECT ...
Edit
If you also want to show all intervals, even if they have no values, I think that the best you can do is to have a table Intervals
that contains all intervals that you need:
CREATE TABLE Intervals (
reginterval time
);
INSERT INTO Intervals VALUES
('09:00:00'),
('09:30:00'),
('10:00:00'),
...
This query returns all intervals, combined with all dates present in your table:
SELECT Dates.regdate, Intervals.reginterval
FROM
(SELECT DISTINCT regdate FROM Data) Dates,
Intervals
And this query returns the rows you need:
SELECT
di.regdate,
di.reginterval,
COUNT(CASE WHEN Data.items='item1' THEN 1 END) item1,
COUNT(CASE WHEN Data.items='item2' THEN 1 END) item2,
COUNT(CASE WHEN Data.items='item3' THEN 1 END) item3,
COUNT(CASE WHEN Data.items='item4' THEN 1 END) item4
FROM (
SELECT Dates.regdate, Intervals.reginterval
FROM (SELECT DISTINCT regdate FROM Data) Dates,
Intervals
) di
LEFT JOIN Data
ON di.regdate=Data.regdate
AND di.reginterval=SEC_TO_TIME(TRUNCATE(TIME_TO_SEC(Data.regtime)/(60*30),0)*(60*30))
GROUP BY
regdate,
reginterval;
Please see fiddle here.
How does this work
The idea here is to convert regtime
, which is a field that contains a time, to the number of seconds since the beginning of the day, using TIME_TO_SEC function:
TIME_TO_SEC(regtime)
we then divide this number to 60*30 which is the number of second in 30 minutes, keeping only the integer part:
TRUNCATE(number_of_seconds/(60*30), 0)
then we multiply the integer part back to 60*30 to obtain the number of seconds, rounded by 60*30 seconds (30 minutes).
with SEC_TO_TIME we convert the number of seconds back to a time field.