sql >> Databasteknik >  >> RDS >> Sqlserver

SQL Count för att inkludera nollvärden

Inte så mycket WHERE-satsen, utan GROUP BY. Frågan returnerar endast data för rader som finns. Det betyder att när du grupperar efter datumet för tidsstämpeln kommer endast dagar för vilka det finns rader att returneras. SQL Server kan inte veta från sammanhanget att du vill "fylla i tomrummen", och den skulle inte veta vad med.

Det normala svaret är en CTE som producerar alla dagar du vill se och fyller på så sätt i tomrummen. Den här är lite knepig eftersom den kräver en rekursiv SQL-sats, men det är ett välkänt knep:

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

För att bryta ner det, använder CTE en fackförening som refererar till sig själv för att rekursivt lägga till en dag i taget till föregående datum och komma ihåg det datumet som en del av tabellen. Om du körde en enkel sats som använde CTE och bara valde * från den, skulle du se en lista med datum mellan start och slut. Sedan sammanfogar satsen den här listan med datum till loggtabellen baserat på loggtidsstämpeldatumet, samtidigt som datum som inte har några loggposter bevaras med hjälp av den vänstra kopplingen (tar alla rader från "vänster" sida oavsett om de har matchande rader på " höger sida eller inte). Slutligen grupperar vi efter datum och räknar istället och vi borde få det svar du vill ha.



  1. EF6 med MySQL. Den angivna nyckeln fanns inte i ordboken

  2. Drupal databasstruktur – effektiv/ineffektiv?

  3. Avancerad SQL Query Design Hjälp (Duplicerar över två tabeller, flera fält, möjliga undantag baserat på ett fält)

  4. MYSQL Case i select-satsen för kontroll av null