Django 窗口注解,使用组合式分句。
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django 窗口注解,使用组合式分句。相关的知识,希望对你有一定的参考价值。
我有一个Django模型,存储在Postgres DB中,由不规则间隔的计数值组成。
WidgetCount
- Time
- Count
我试图使用一个带有Lag的窗口函数来给我提供前一行的值作为注释。我的问题是,当我试图将其与一些明显的日期截断结合起来时,窗口函数使用的是源行而不是明显的分组行。
例如,如果我有以下行,我想返回一个查询器。
time count
2020-01-20 05:00 15
2020-01-20 06:00 20
2020-01-20 09:00 30
2020-01-21 06:00 35
2020-01-21 07:00 40
2020-01-22 04:00 50
2020-01-22 06:00 54
2020-01-22 09:00 58
我想返回一个显示每天第一个读数的查询集,我可以使用:
from django.db.models.functions import Trunc
WidgetCount.objects.distinct("date").annotate(date=Trunc("time", "day"))
这样我就得到了:
date count
01/01/20 15
01/01/21 35
01/01/22 50
我想添加一个注释,给我昨天的值(所以我可以显示每天的变化)。
date count yesterday_count
01/01/20 15
01/01/21 35 15
01/01/22 50 35
如果我这样做。
from django.db.models.functions import Trunc, Lag
from django.db.models import Window
WidgetCount.objects.distinct("date").annotate(date=Trunc("time", "day"), yesterday_count=Window(expression=Lag("count")))
第二行返回的yesterday_count的值是30,也就是说,在应用分明子句之前,它显示的是前一行。
如果我添加一个partiion子句,就像这样。
WidgetCount.objects.distinct("date").annotate(date=Trunc("time", "day"), yesterday_count=Window(expression=Lag("count"), partition_by=F("date")))
那么 yesterday_count 在所有的行中都是 None.
如果我需要的话,我可以用Python来做这个计算,但是这让我有点抓狂,我想知道我想做的事情是否可行。
谢谢!我有一个Django模型存储在Django中。
我认为主要的问题是,你混合了在注释中使用的操作,生成一个分组查询集,如sum和一个模拟为给定查询集中的每个记录创建一个新字段的操作,如 yesterday_count=Window(expression=Lag("count"))
.
所以在这里订购真的很重要。所以当你尝试的时候。
WidgetCount.objects.distinct("date").annotate(date=Trunc("time", "day"), yesterday_count=Window(expression=Lag("count")))
结果查询集只是简单的WidgetCount.objects.distinct("date")注释,没有进行分组。
我建议将你的操作解耦,这样会变得更容易理解发生了什么,并且注意你是在python对象上迭代,所以不需要做任何新的查询!
注意在使用SUM操作作为例子,因为我在使用FirstValue操作符时得到一个意外的错误。所以我用SUM来发帖,来演示这个想法,这个想法还是一样的。对于FirstValue的想法应该是一样的,只是改变一下 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)
OUTPUT.FirstValue操作符需要使用Windows函数,所以不能嵌套FirtValue然后计算Lag,所以在这种情况下,我不知道你是否能做到。
{'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}
所以不能先嵌套FirtValue再计算Lag 所以在这种情况下,我不确定你是否可以这样做 问题就变成了如何在不嵌套windows的情况下访问First_Value列。
我还没有在本地测试过,但我认为你想要 GROUP BY
而不是使用 DISTINCT
在这里。
WidgetCount.objects.values(
date=Trunc('time', 'day'),
).order_by('date').annotate(
date_count=Sum('count'), # Will trigger a GROUP BY date
).annotate(
yesterday_count=Window(Lag('date_count')),
)
以上是关于Django 窗口注解,使用组合式分句。的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Django Summernote 中显示编程片段的代码块?