sql >> Base de Datos >  >> RDS >> PostgreSQL

Anotación de ventana de Django usando combinado con cláusula distinta

Creo que el problema principal es que está mezclando operaciones que se usan en la anotación y generan un conjunto de consultas agrupadas, como sum, con una operación que simplemente crea un nuevo campo para cada registro en el conjunto de consultas dado, como yesterday_count=Window(expression=Lag("count")) .

Así que ordenar realmente importa aquí. Así que cuando intentes:

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

El conjunto de consultas resultante es simplemente el WidgetCount.objects.distinct("fecha") anotado, no se realiza ninguna agrupación.

Sugeriría desacoplar sus operaciones para que sea más fácil comprender lo que está sucediendo, y observe que está iterando sobre el objeto python, ¡así que no necesita realizar nuevas consultas!

Tenga en cuenta el uso de la operación SUM como ejemplo porque recibo un error inesperado con el operador FirstValue. Así que estoy publicando con Sum para demostrar la idea que sigue siendo la misma. La idea debería ser la misma para el primer valor simplemente cambiando acc_count=Sum("count") a 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)

SALIDA:

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

Resulta que el operador FirstValue requiere el uso de una función de Windows, por lo que no puede anidar FirtValue y luego calcular Lag, por lo que en este escenario no estoy exactamente seguro de si puede hacerlo. La pregunta es cómo acceder a la columna First_Value sin anidar ventanas.