【问题标题】:How to build Django Query Expression for Window function如何为窗口函数构建 Django 查询表达式
【发布时间】:2019-03-28 16:02:12
【问题描述】:

我有 postgres 查询,我想使用 Django QuerySet builder 来表示它

我有一张桌子: 历史事件

date -------------------------- amount
2019-03-16 16:03:11.49294+05    250.00
2019-03-18 14:56:30.224846+05   250.00
2019-03-18 15:07:30.579531+05   250.00
2019-03-18 20:52:53.581835+05   5.00
2019-03-18 22:33:21.598517+05   1000.00
2019-03-18 22:50:57.157465+05   1.00
2019-03-18 22:51:44.058534+05   2.00
2019-03-18 23:11:29.531447+05   255.00
2019-03-18 23:43:43.143171+05   250.00
2019-03-18 23:44:47.445534+05   500.00
2019-03-18 23:59:23.007685+05   250.00
2019-03-19 00:01:05.103574+05   255.00
2019-03-19 00:01:05.107682+05   250.00
2019-03-19 00:01:05.11454+05    500.00
2019-03-19 00:03:48.182851+05   255.00

我需要使用此数据构建图形,并按日期逐步递增金额总和

此 SQL 收集正确的数据:

with data as (
  select
    date(date) as day,
    sum(amount) as day_sum
  from history_event
  group by day
)
select
  day,
  day_sum,
  sum(day_sum) over (order by day asc rows between unbounded preceding and current row)
from data

但我不明白如何为此构建正确的查询集表达式

另一个问题 - 几天没有数据,它们也没有出现在我的图表上

【问题讨论】:

  • 看窗口函数docs
  • 答案有帮助吗?

标签: django python-3.x postgresql


【解决方案1】:

像您这样的嵌套查询无法在 ORM 语法中轻松定义。 Subquery 仅限于返回单个值的相关子查询。这通常会导致您可以轻松地用 SQL 表达的查询的 ORM 变通办法扭曲且效率低下。

在这种情况下,您可以将两个窗口函数与不同的子句结合使用。

result = (Event.objects
    .values('date', 'amount')
    .annotate(day_sum=Window(
        expression=Sum('amount'),
        partition_by=[F('date')],
    ))
    .annotate(total=Window(
        expression=Sum('amount'),
        frame=RowRange(start=None, end=0),
        order_by=F('date').asc(),
    ))
    .distinct('date')       
    .order_by('date', '-total')
)

您需要按'-total' 订购,否则distinct 会丢弃错误的行,导致total 中的数量少于正确的数量。

关于失踪的日子; SQL 没有固有的日历概念(因此缺少日期),除非您有大量数据,否则在 Python 循环中添加缺少的日期应该更容易。在 SQL 中,您可以使用 calendar table

【讨论】:

    猜你喜欢
    • 2021-07-09
    • 2017-10-03
    • 2018-09-03
    • 2018-11-14
    • 1970-01-01
    • 1970-01-01
    • 2013-07-15
    • 1970-01-01
    • 2022-01-19
    相关资源
    最近更新 更多