Zazwyczaj osiągasz tego typu rzeczy, dołączając do tabeli wartości , czyli tabelę zawierającą wszystkie interesujące Cię wartości.
Typowe tabele wartości mogą zawierać na przykład wszystkie wartości całkowite z przedziału od 0 do 1000 lub wszystkie daty w danym okresie. Często tabele wartości zawierają więcej wartości niż jest to pożądane i uzyskujemy dokładnie pożądane dane wyjściowe, dodając filtry w klauzuli WHERE.
W takim przypadku będziesz potrzebować takiej tabeli, która zawiera daty. Zakładając, że ta tabela nosi nazwę ValTableDates i zawiera wszystkie daty między styczniem 2005 a grudniem 2010, zapytanie wyglądałoby tak:
SELECT AVG(data) AS data, VT.ValDate
FROM ValTableDates VT
LEFT JOIN table T ON T.dateReg = VT.ValDate
WHERE VT.ValDate > [Some Start Date] and VT < [Some End Date]
GROUP BY YEAR(dateReg), MONTH(dateReg), DAY(dateReg)
ORDER BY dateReg
Powyższe zapytanie może wymagać nieco dopracowania, aby uzyskać wartość Zero zamiast NULL, ale głównym punktem jest to, że Tabela wartości jest zazwyczaj najprostszym sposobem dostarczenia rekordów wyjściowych dla brakujących punktów danych.
Alternatywą jest użycie funkcja/wyrażenie, które tworzy żądaną sekwencję [data] wewnątrz podzapytania, ale jest to generalnie mniej wydajne i bardziej podatne na błędy.