2010-06-22 4 views
5

Sto provando a scrivere una query MySQL per ottenere un valore medio al mese, per tutti i mesi compresi tra le date specificate. La mia idea è questa:Seleziona tutti i mesi entro un determinato intervallo di date, compresi quelli con valori 0

Query, qualcosa come

SELECT AVG(value1) as avg_value_1, 
AVG(value2) as avg_value_2, 
MONTH(save_date) as month, 
YEAR(save_date) as year 
FROM myTable 
WHERE save_date BETWEEN '2009-01-01' AND '2009-07-01' 
GROUP BY YEAR(save_date), MONTH(save_date) 

avg_value_1 | avg_value_2 | month | year 
    5  |  4  | 1 | 2009 
    2  |  1  | 2 | 2009 
    7  |  5  | 3 | 2009 
    0  |  0  | 4 | 2009 <--- 
    6  |  5  | 5 | 2009 
    3  |  6  | 6 | 2009 

Vedete, senza valori sono stati inseriti nel mese di aprile del 2009, ma voglio che si mostrano come un, valore 0 0 in uscita. Qualche idea su come raggiungere questo obiettivo? Può essere fatto in MySQL?

risposta

6

Sono d'accordo con la risposta di Lieven creare una tabella contenente tutti i mesi che potresti mai richiedere e usarla per "LEFT JOIN" nella tabella dei risultati. Ricorda, questa è una tabella molto piccola, solo 365 (ish) righe all'anno di dati che hai ... E puoi facilmente scrivere del codice per popolare questa tabella inizialmente

Facciamo questo qui, e dà un sacco di i vantaggi, ad esempio, immagina una tabella di dati mensile con i seguenti campi (e tutti gli altri che puoi immaginare!) completamente popolati per tutti i mesi in un dato intervallo;

  • data (ad esempio 2009-04-01)
  • giorno (ad esempio 1)
  • giorno della settimana (ad esempio il Mercoledì)
  • mese (ad esempio 4)
  • dell'anno (ad esempio 2009)
  • Esercizio (Eg 2009/10)
  • Financial Quarter (Eg 2009Q1)
  • Calendar Quarter (Eg 2009Q2)
  • 0.123.516,41 mila

Quindi combinare questo con la query sopra, come segue;

 
SELECT `DT`.`myYear`, `DT`.`myMonth`, 
      AVG(`myTable`.`value1`) as avg_value_1, 
      AVG(`myTable`.`value2`) as avg_value_2 

FROM `dateTable` as DT 
LEFT JOIN `myTable` 
    ON `dateTable`.`myDate` = `myTable`.`save_date` 

WHERE `dateTable`.`myDate` BETWEEN '2009-01-01' AND '2009-07-01' 

GROUP BY `DT`.`myYear`, `DT`.`myMonth` 

Ci possono essere alcuni errori nel mio codice SQL come io non sono stato in grado di creare le tabelle di test, ma spero che si otterrà il capitale e alterare per soddisfare le vostre esigenze!

Con questo, è possibile modificare la "GROUP BY" clausola a tutto ciò che si ha nella tabella "dateTable", che può permettere di segnalare facilmente Financial Quarter, mese, giorno, giorno della settimana, ecc

Spero che questo aiuti!

2

Il modo più semplice è probabilmente quello di creare una tabella di date contenente mesi e anni e associarla al risultato finale.

+0

Grazie per la risposta, ma ho davvero bisogno di una tabella contenente tutte le date possibili? Questo non può essere il modo più semplice! :) –

+0

È difficile restituire valori che non esistono. :) –

+0

Buon punto Lieven, ma MySQL conosce tutte le date a memoria, quando si usano i normali GetDate() e DateAdd() e così via ... Mi sembra che ci debba essere un modo per recuperarli! –