Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Conteggio SQL per includere valori zero

Non tanto la clausola WHERE, ma il GROUP BY. La query restituirà solo i dati per le righe esistenti. Ciò significa che quando si raggruppa in base alla data del timestamp, verranno restituiti solo i giorni per i quali sono presenti righe. SQL Server non può sapere dal contesto che vuoi "riempire gli spazi vuoti" e non saprebbe con cosa.

La risposta normale è un CTE che produce tutti i giorni che vuoi vedere, riempiendo così gli spazi vuoti. Questo è un po' complicato perché richiede un'istruzione SQL ricorsiva, ma è un trucco ben noto:

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

Scomponendolo, il CTE utilizza un'unione che fa riferimento a se stessa per aggiungere ricorsivamente un giorno alla volta alla data precedente e ricordare quella data come parte della tabella. Se esegui una semplice istruzione che utilizza il CTE e seleziona * da esso, vedrai un elenco di date tra l'inizio e la fine. Quindi, l'istruzione unisce questo elenco di date alla tabella di registro in base alla data del timestamp del registro, preservando le date che non hanno voci di registro utilizzando il join sinistro (prende tutte le righe dal lato "sinistra" se hanno righe corrispondenti su " destra" o meno). Infine, raggruppiamo per data e contiamo invece e dovremmo ottenere la risposta che desideri.