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

SQL-tæller for at inkludere nulværdier

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.



  1. Hvordan kan jeg gruppere børn og forældre i en enkelt forespørgsel?

  2. Sådan får du det aktuelle Auto_Increment-sekvensnummer til MySQL / MariaDB-tabel

  3. Vil du flette JSONB-værdier i PostgreSQL?

  4. Aktivering af TLS i R12.1