PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Django:Gruppe nach Monat abfragen

Zuerst müssen Sie eine Funktion erstellen, die den Monat für Sie extrahieren kann:

from django.db import models
from django.db.models import Func

class Month(Func):
    function = 'EXTRACT'
    template = '%(function)s(MONTH from %(expressions)s)'
    output_field = models.IntegerField()

Danach müssen Sie nur noch

  1. Beschrifte jede Zeile mit dem Monat
  2. gruppieren Sie die Ergebnisse nach dem annotierten Monat mit values()
  3. Kommentieren Sie jedes Ergebnis mit der aggregierten Summe der Gesamtwerte unter Verwendung von Sum()

Wichtig :Wenn Ihre Modellklasse eine in den Metaoptionen angegebene Standardreihenfolge hat, müssen Sie ein leeres order_by() hinzufügen Klausel. Dies liegt an https://docs.djangoproject.com/en/1.9/topics/db/aggregation/#interaction-with-default-ordering-or-order-by

Felder, die in order_by() erwähnt werden Teil eines Abfragesatzes (oder die in der Standardreihenfolge eines Modells verwendet werden) werden bei der Auswahl der Ausgabedaten verwendet, auch wenn sie in values() nicht anders angegeben sind Forderung. Diese zusätzlichen Felder werden verwendet, um "Gefällt mir"-Ergebnisse zusammenzufassen, und sie können ansonsten identische Ergebniszeilen als getrennt erscheinen lassen.

Wenn Sie sich nicht sicher sind, können Sie einfach das leere order_by() hinzufügen Klausel trotzdem ohne nachteilige Auswirkungen.

d.h.

from django.db.models import Sum

summary = (Invoice.objects
              .annotate(m=Month('date'))
              .values('m')
              .annotate(total=Sum('total'))
              .order_by())

Den vollständigen Kern finden Sie hier:https://gist.github.com/alvingonzales/ff9333e39d221981e5fc4cd6cdafdd17

Wenn Sie weitere Informationen benötigen:

Details zum Erstellen eigener Func-Klassen:https://docs.djangoproject.com/en/1.8/ref/models/expressions/#func-expressions

Details zur Klausel values() (achten Sie darauf, wie sie mit annotate() in Bezug auf die Reihenfolge der Klauseln interagiert):https://docs.djangoproject.com/en/1.9/topics/db/aggregation/#values

Die Reihenfolge, in der annotate()- und values()-Klauseln auf eine Abfrage angewendet werden, ist wichtig. Wenn die Klausel values() vor der Klausel annotate() steht, wird die Anmerkung unter Verwendung der durch die Klausel values() beschriebenen Gruppierung berechnet.