Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

SQL-Anzahl, um Nullwerte einzuschließen

Nicht so sehr die WHERE-Klausel, sondern die GROUP BY. Die Abfrage gibt nur Daten für vorhandene Zeilen zurück. Das heißt, wenn Sie nach dem Datum des Zeitstempels gruppieren, werden nur Tage zurückgegeben, für die Zeilen vorhanden sind. SQL Server kann aus dem Kontext nicht erkennen, dass Sie „die Lücken ausfüllen“ möchten, und er wüsste nicht, womit.

Die normale Antwort ist ein CTE, der alle Tage erzeugt, die Sie sehen möchten, und somit die Lücken füllt. Dies ist ein wenig knifflig, weil es eine rekursive SQL-Anweisung erfordert, aber es ist ein bekannter 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

Der CTE verwendet eine Vereinigung, die auf sich selbst verweist, um rekursiv jeweils einen Tag zum vorherigen Datum hinzuzufügen und sich dieses Datum als Teil der Tabelle zu merken. Wenn Sie eine einfache Anweisung ausführen, die den CTE verwendet und einfach * daraus ausgewählt hat, sehen Sie eine Liste mit Daten zwischen Start und Ende. Dann verbindet die Anweisung diese Liste von Daten mit der Protokolltabelle basierend auf dem Datum des Protokollzeitstempels, während Daten ohne Protokolleinträge mithilfe der linken Verknüpfung beibehalten werden (nimmt alle Zeilen von der "linken" Seite, ob sie übereinstimmende Zeilen auf der " rechte" Seite oder nicht). Schließlich gruppieren wir nach Datum und zählen stattdessen und wir sollten die gewünschte Antwort erhalten.