Domanda

C'è un modo semplice per fare un GROUP BY DATE (timestamp) che include tutti i giorni in un periodo di tempo, indipendentemente dal fatto che ci siano record associati a quella data?

Fondamentalmente, devo generare un rapporto come questo:

24 Dec - 0 orders
23 Dec - 10 orders
22 Dec - 8 orders
21 Dec - 2 orders
20 Dec - 0 orders
È stato utile?

Soluzione

Invece di utilizzare GROUP BY, crea una tabella (forse una tabella temporanea) che contenga le date specifiche desiderate, ad esempio:

24 Dec
23 Dec
22 Dec
21 Dec
20 Dec

Quindi, unisci quella tabella alla tabella Ordini.

Altri suggerimenti

Supponendo che tu abbia più ordini che date potrebbe funzionare qualcosa del genere:

select date, count(id) as orders
from
(
  SELECT DATE_ADD('2008-01-01', INTERVAL @rn:=@rn+1 DAY) as date from (select @rn:=-1)t, `order` limit 365
) d left outer join `order` using (date)
group by date

Un metodo è quello di creare una tabella del calendario e unirsi ad essa.

Lo creerei in modo permanente, quindi creerei un'attività che inserirà nuove date, che potrebbe essere eseguita settimanalmente, giornalmente, mensilmente, ecc.

Nota, presumo che stai convertendo il tuo timestamp in una data.

devi generare un set di risultati intermedi con tutte le date che vuoi includere nell'output ...

se lo stai facendo in un proc memorizzato, potresti creare una tabella temporanea o una variabile di tabella (non conosco le funzionalità di MySQL), ma una volta che hai tutte le date in una tabella o in un set di risultati di qualche tipo

Basta unirsi ai dati reali dalla tabella temporanea, usando un join esterno

In SQL Server sarebbe così

  Declare @Dates Table (aDate DateTime Not Null)
  Declare @StartDt DateTime Set @StartDt = 'Dec 1 2008'
  Declare @EndDt   DateTime Set @EndDt   = 'Dec 31 2008'
  While @StartDt < @EndDt Begin
    Insert @Dates(aDate) Values(@StartDt)
    Set @StartDt = DateAdd(Day, 1, @StartDt)
  End

   Select D.aDate, Count(O.*) Orders
   From @Dates D Left Join 
      OrderTable O On O.OrderDate = D.aDate
   Group By D.aDate

In un data warehouse, il metodo utilizzato è quello di creare una tabella che contenga tutte le date e creare una chiave esterna tra i dati e la tabella delle date. Non sto dicendo che questo è il modo migliore di procedere nel tuo caso, ma solo che è la migliore pratica nei casi in cui è necessario eseguire il rollup di grandi quantità di dati in vari modi ai fini della segnalazione.

Se si utilizza un livello di reporting su SQL Server, è possibile semplicemente scrivere una logica per inserire le date mancanti nell'intervallo di interesse dopo la restituzione dei dati e prima di eseguire il rendering del report.

Se stai creando i tuoi report direttamente da SQL Server e non hai già un data warehouse e non c'è il tempo o non è necessario crearne uno in questo momento, vorrei creare una tabella delle date e unirmi ad essa. La formattazione necessaria per eseguire il join e ottenere l'output desiderato potrebbe essere un po 'complicata, ma riuscirà a fare il lavoro.

C'è un modo abbastanza semplice per farlo ... tranne per il fatto che non me lo ricordo. Ma ho adattato questa query da questa discussione :

SELECT 
    DISTINCT(LEFT(date_field,11)) AS `Date`,
    COUNT(LEFT(date_field,11)) AS `Number of events`
FROM events_table
GROUP BY `Date`

Funziona anche in MySQL

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top