sql >> Database >  >> RDS >> PostgreSQL

Django:Groep per maand zoeken

Eerst moet je een functie maken die de maand voor je kan extraheren:

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()

Daarna hoef je alleen maar

  1. annoteer elke rij met de maand
  2. groepeer de resultaten op de geannoteerde maand met behulp van values()
  3. annoteer elk resultaat met de geaggregeerde som van de totalen met behulp van Sum()

Belangrijk :als uw modelklasse een standaardvolgorde heeft gespecificeerd in de meta-opties, dan moet u een lege order_by() toevoegen clausule. Dit komt door https://docs.djangoproject.com/en/1.9/topics/db/aggregation/#interaction-with-default-ordering-or-order-by

Velden die worden vermeld in de order_by() deel van een queryset (of die worden gebruikt in de standaardvolgorde op een model) worden gebruikt bij het selecteren van de uitvoergegevens, zelfs als ze niet anders zijn gespecificeerd in de values() telefoongesprek. Deze extra velden worden gebruikt om "vind ik leuk" resultaten te groeperen en ze kunnen anders identieke resultaatrijen laten lijken alsof ze gescheiden zijn.

Als je het niet zeker weet, kun je gewoon de lege order_by() . toevoegen clausule toch zonder nadelige gevolgen.

d.w.z.

from django.db.models import Sum

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

Zie hier de volledige kern:https://gist.github.com/alvingonzales/ff9333e39d221981e5fc4cd6cdafdd17

Als je meer informatie nodig hebt:

Details over het maken van uw eigen Func-klassen:https://docs.djangoproject.com/en/1.8/ref/models/expressions/#func-expressions

Details over de clausule values() (let op hoe deze samenwerkt met annotate() met betrekking tot de volgorde van de clausules):https://docs.djangoproject.com/en/1.9/topics/db/aggregation/#values

de volgorde waarin de clausules annotate() en values() op een query worden toegepast, is belangrijk. Als de clausule values() voorafgaat aan de clausule annotate(), wordt de annotatie berekend met behulp van de groepering die wordt beschreven door de clausule values().



  1. Vraag en aanbod afstemmen - Oplossingen, deel 3

  2. Interval converteren naar minuten

  3. Een tekenreeks converteren naar een datum/tijd in SQL Server met PARSE()

  4. Wat is de standaardnaam van de beperking in PostgreSQL?