Ikke så meget WHERE-sætningen, men GROUP BY. Forespørgslen returnerer kun data for rækker, der eksisterer. Det betyder, at når du grupperer efter datoen for tidsstemplet, vil kun dage, hvor der er rækker, blive returneret. SQL Server kan ikke vide fra kontekst, at du vil "udfylde de tomme felter", og den ville ikke vide hvad med.
Det normale svar er en CTE, der producerer alle de dage, du vil se, og dermed udfylder de tomme felter. Denne er lidt vanskelig, fordi den kræver en rekursiv SQL-sætning, men det er et velkendt trick:
WITH CTE_Dates AS
(
SELECT @START AS cte_date
UNION ALL
SELECT DATEADD(DAY, 1, cte_date)
FROM CTE_Dates
WHERE DATEADD(DAY, 1, cte_date) <= @END
)
SELECT
cte_date as TIME_STAMP,
ISNULL(COUNT(HL_Logs.Time_Stamp), 0) AS counted_leads,
FROM CTE_Dates
LEFT JOIN HL_Logs ON DATEADD(dd, 0, DATEDIFF(dd, 0, Time_Stamp)) = cte_date
WHERE Time_Stamp between @BEGIN and @END and ID_Location = @LOCATION
GROUP BY cte_date
For at opdele det, bruger CTE en fagforening, der refererer til sig selv til rekursivt at tilføje en dag ad gangen til den foregående dato og huske denne dato som en del af tabellen. Hvis du kørte en simpel erklæring, der brugte CTE og bare valgte * fra den, ville du se en liste over datoer mellem start og slut. Derefter forbinder sætningen denne liste over datoer med logtabellen baseret på datoen for logtidsstemplet, mens de bevarer datoer, der ikke har nogen logindgange ved hjælp af den venstre joinforbindelse (tager alle rækker fra "venstre" side, uanset om de har matchende rækker på " højre side eller ej). Til sidst grupperer vi efter dato og tæller i stedet, og vi burde få det svar, du ønsker.