Wygeneruj jednokolumnową dates_hours
tabela zawierająca wszystkie daty i godziny z rozsądnego zakresu (np. od 1900 do 2200). Następnie wykonaj LEFT JOIN
z tej tabeli do bieżącego zapytania.
Aby ta technika działała poprawnie, prawdopodobnie będziesz musiał dodać do tabeli zaindeksowaną kolumnę, która zawiera przekonwertowany znacznik czasu (Twój copied_timestamp
przekonwertowano na DATETIME
, w zaokrągleniu do godziny)
SELECT date_hour, count(req.converted_timestamp)
FROM
dates_hours
LEFT JOIN req ON req.converted_timestamp = dates_hours.date_hour
WHERE date_hour
BETWEEN (SELECT MIN(req.converted_timestamp) FROM req)
AND (SELECT MAX(req.converted_timestamp) FROM req)
GROUP BY date_hour
Aby wygenerować dates_hours
tabela:
CREATE TABLE dates_hours (date_hour DATETIME PRIMARY KEY);
DELIMITER $$$
CREATE PROCEDURE generate_dates_hours (to_date DATETIME)
BEGIN
DECLARE start_date DATETIME;
DECLARE inc INT;
SELECT MAX(date_hour) INTO start_date FROM dates_hours;
IF start_date IS NULL THEN
SET start_date = '1900-01-01';
END IF;
SET inc = 1;
WHILE start_date + INTERVAL inc HOUR <= to_date DO
INSERT INTO dates_hours VALUE (start_date + INTERVAL inc HOUR);
SET inc = inc +1;
END WHILE;
END $$$
DELIMITER ;
CALL generate_dates_hours('2200-01-01');
Dobra, teraz, kiedy sam robię korektę, zdaję sobie sprawę, że jest to dość daleko idące rozwiązanie. Mam nadzieję, że ktoś wymyśli bardziej elegancki.