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

Django-Fensterannotation mit kombinierter Klausel

Ich denke, das Hauptproblem besteht darin, dass Sie Operationen mischen, die in Annotationen verwendet werden, um einen gruppierten Abfragesatz wie sum mit einer Operation zu mischen, die einfach ein neues Feld für jeden Datensatz im angegebenen Abfragesatz erstellt, z. B. yesterday_count=Window(expression=Lag("count")) .

Bestellen ist hier also wirklich wichtig. Also, wenn Sie versuchen:

WidgetCount.objects.distinct("date").annotate(date=Trunc("time", "day"), yesterday_count=Window(expression=Lag("count")))

Der Ergebnisabfragesatz ist einfach mit WidgetCount.objects.distinct("date") annotiert, es wird keine Gruppierung durchgeführt.

Ich würde vorschlagen, Ihre Operationen zu entkoppeln, damit Sie leichter verstehen, was passiert, und bemerken, dass Sie über das Python-Objekt iterieren, also müssen Sie keine neuen Abfragen machen!

Beachten Sie die Verwendung des SUM-Vorgangs als Beispiel, da ich einen unerwarteten Fehler mit dem FirstValue-Operator erhalte. Also poste ich mit Sum, um die Idee zu demonstrieren, die gleich bleibt. Die Idee sollte für den ersten Wert dieselbe sein, nur durch Ändern von acc_count=Sum("count") zu first_count=FirstValue("count")

for truncDate_groups in Row.objects.annotate(trunc_date=Trunc('time','day')).values("trunc_date")\
                      .annotate(acc_count=Sum("count")).values("acc_count","trunc_date")\
                      .order_by('trunc_date')\
                      .annotate(y_count=Window(Lag("acc_count")))\
                      .values("trunc_date","acc_count","y_count"):
    print(truncDate_groups)

AUSGABE:

{'trunc_date': datetime.datetime(2020, 1, 20, 0, 0, tzinfo=<UTC>), 'acc_count': 65, 'y_count': None}
{'trunc_date': datetime.datetime(2020, 1, 21, 0, 0, tzinfo=<UTC>), 'acc_count': 75, 'y_count': 162}
{'trunc_date': datetime.datetime(2020, 1, 22, 0, 0, tzinfo=<UTC>), 'acc_count': 162, 'y_count': 65}

Es stellt sich heraus, dass der FirstValue-Operator eine Windows-Funktion verwenden muss, sodass Sie FirtValue nicht verschachteln und dann Lag berechnen können. In diesem Szenario bin ich mir also nicht ganz sicher, ob Sie dies tun können. Es stellt sich die Frage, wie man auf die First_Value-Spalte zugreifen kann, ohne Fenster zu verschachteln.