PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Annotation Django Window utilisant une clause combinée avec une clause distincte

Je pense que le problème principal est que vous mélangez des opérations utilisées dans l'annotation pour générer un ensemble de requêtes groupées telles que sum avec une opération qui crée simplement un nouveau champ pour chaque enregistrement dans l'ensemble de requêtes donné, tel que yesterday_count=Window(expression=Lag("count")) .

Donc, la commande est vraiment importante ici. Ainsi, lorsque vous essayez :

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

Le jeu de requêtes résultant est simplement le WidgetCount.objects.distinct("date") annoté, aucun regroupement n'est effectué.

Je suggérerais de découpler vos opérations afin qu'il devienne plus facile de comprendre ce qui se passe, et notez que vous parcourez l'objet python, vous n'avez donc pas besoin de faire de nouvelles requêtes !

Remarque en utilisant l'opération SUM comme exemple car je reçois une erreur inattendue avec l'opérateur FirstValue. Je poste donc avec Sum pour démontrer l'idée qui reste la même. L'idée devrait être la même pour la première valeur en changeant simplement acc_count=Sum("count") à 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)

SORTIE :

{'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}

Il s'avère que l'opérateur FirstValue nécessite l'utilisation d'une fonction Windows afin que vous ne puissiez pas imbriquer FirtValue puis calculer le décalage, donc dans ce scénario, je ne sais pas exactement si vous pouvez le faire. La question devient de savoir comment accéder à la colonne First_Value sans fenêtres imbriquées.