Myslím, že hlavním problémem je, že mícháte operace, které se používají v anotaci, generují seskupenou sadu dotazů, jako je suma, s operací, která jednoduše vytvoří nové pole pro každý záznam v dané sadě dotazů, jako je yesterday_count=Window(expression=Lag("count"))
.
Takže na objednávce zde opravdu záleží. Takže když to zkusíte:
WidgetCount.objects.distinct("date").annotate(date=Trunc("time", "day"), yesterday_count=Window(expression=Lag("count")))
Výsledná sada dotazů je jednoduše anotovaná WidgetCount.objects.distinct("date"), neprovádí se žádné seskupování.
Navrhoval bych oddělit vaše operace, aby bylo snazší porozumět tomu, co se děje, a všimněte si, že iterujete přes objekt python, takže nemusíte zadávat žádné nové dotazy!
Všimněte si při použití operace SUM jako příkladu, protože dostávám neočekávanou chybu s operátorem FirstValue. Takže posílám příspěvek se Sumem, abych demonstroval myšlenku, která zůstává stejná. Nápad by měl být stejný pro první hodnotu, stačí změnit acc_count=Sum("count")
na 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)
VÝSTUP:
{'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}
Ukazuje se, že operátor FirstValue vyžaduje použití funkce Windows, takže nemůžete vnořit FirtValue a poté vypočítat zpoždění, takže v tomto scénáři si nejsem úplně jistý, jestli to dokážete. Otázkou je, jak získat přístup ke sloupci First_Value bez vnoření oken.