2013-08-07 15 views
7

È possibile riprodurre la seguente query mysql in Django senza utilizzare il metodo select?Gruppo Django per date e valori SUM

MariaDB [db1]> SELECT datetime, SUM(datas) FROM table AND datetime BETWEEN '2013-07-26 13:00:00' AND '2013-07-26 23:00:00' GROUP BY datetime; 

Per ottenere questo tipo di risultato:

+---------------------+-----------+ 
| datetime   | SUM(data) | 
+---------------------+-----------+ 
| 2013-07-26 13:00:00 |  489 | 
| 2013-07-26 14:00:00 |  2923 | 
| 2013-07-26 15:00:00 |  984 | 
| 2013-07-26 16:00:00 |  2795 | 
| 2013-07-26 17:00:00 |  1308 | 
| 2013-07-26 18:00:00 |  1365 | 
| 2013-07-26 19:00:00 |  1331 | 
| 2013-07-26 20:00:00 |  914 | 
| 2013-07-26 21:00:00 |  919 | 
| 2013-07-26 22:00:00 |  722 | 
| 2013-07-26 23:00:00 |  731 | 
+---------------------+-----------+ 
11 rows in set (1.45 sec) 

Edit: Ho ottenuto per ora questo tipo di query:

>>> value = table.objects.filter(datetime__range=('2013-07-26 13:00:00', 
'2013-07-26 23:00:00')).values('datetime', 'data').annotate(Sum('data')) 

>>> print value.query 
SELECT `table`.`datetime`, `table`.`data` SUM(`table`.`imps`) AS `data__sum` 
FROM `table` 
WHERE `table`.`datetime` BETWEEN 2013-07-26 13:00:00 
and 2013-07-26 23:00:00 GROUP BY `table`.`datetime`, 
`table`.`data` ORDER BY NULL 

Perché somma operare sia su datetime e dei dati?

Ho cercato ovunque su django doc, qui in pila ma non ho trovato nulla di coerente con il mio problema. Qualche suggerimento?

+1

Cosa SQL fa il tuo set di query genera? Puoi usare 'print values.query' –

+0

Cambia l'ordine di' .annotate() 'e' .values ​​() ' –

risposta

6

Hmm si utilizza Count, si dovrebbe usare Sum, e values() determinerà ciò che accade in GROUP BY così si dovrebbe usare values('datetime') solo. Il vostro set di query dovrebbe essere qualcosa di simile:

from django.db.models import Sum 

values = self.model.objects.filter(
    datetime__range=(self.dates[0], self.dates[1]) 
).values('datetime').annotate(data_sum=Sum('data')) 

anche se non sono così sicuro circa l'ordine del filter(), quindi potrebbe essere questo:

values = self.model.objects.values('datetime').annotate(data_sum=Sum('data')).filter(
    datetime__range=(self.dates[0], self.dates[1]) 
) 

Immagino che ci si vuoi provare sia poi . Se volete vedere la query grezzo di coloro set di query, utilizzare Queryset.query:

print self.model.objects.filter(
    datetime__range=(self.dates[0], self.dates[1]) 
).values('datetime').annotate(data_sum=Sum('data')).query.__str__() 

in modo da poter essere sicuri di ottenere la query giusta.

Spero che aiuti.

+1

thx, perché filtrare dopo l'annotazione? – tbenett

+1

E 'solo che non sono sicuro della loro query di risultati, quindi potrebbe essere, comunque, usare 'query .__ str __()' per verificare la query di cui hai bisogno. Controlla anche la mia risposta con attenzione, dovresti usare i valori ('datetime') 'solo –

+0

Puoi modificare la risposta per indicare quale risposta è stata corretta? – Jglstewart

4

order_by() ti porterà GROUP BY:

values = self.model.objects.filter(datetime__range=(
    self.dates[0], self.dates[1])) \ 
    .values('datetime') \ 
    .annotate(data_sum=Sum('datas') \ 
    .order_by()) 
+0

Non funziona, mi dispiace: SELECT 'table' .datetime',' table' .data' FROM 'table' WHERE' table' .datetime' TRA 2013-07-26 13:00:00 e 2013-07 -26 23:00:00) ORDINA PER: table' .datetime' ASC – tbenett

+0

E adesso? –

+0

Va bene io uso i metodi di Hieu Nguyen e il problema deriva dai valori ('datetime', 'data') – tbenett