【问题标题】:Django + PostgreSQL: Fill missing dates in a rangeDjango + PostgreSQL:在一个范围内填充缺失的日期
【发布时间】:2015-10-19 09:19:27
【问题描述】:

我有一张表,其中一列是date。每个日期可以有多个条目。

date         .....
-----------  -----
2015-07-20     ..
2015-07-20     ..
2015-07-23     ..
2015-07-24     ..

我想使用 Django ORM 和 PostgreSQL 作为数据库后端以下列形式获取数据:

date         count(date)
-----------  -----------
2015-07-20        2
2015-07-21        0       (missing after aggregation)
2015-07-22        0       (missing after aggregation)
2015-07-23        1
2015-07-24        1

对应的PostgreSQL查询:

WITH RECURSIVE date_view(start_date, end_date) 
AS ( VALUES ('2015-07-20'::date, '2015-07-24'::date) 
     UNION ALL SELECT start_date::date + 1, end_date 
     FROM date_view 
     WHERE start_date < end_date ) 
SELECT start_date, count(date) 
FROM date_view LEFT JOIN my_table ON date=start_date 
GROUP BY date, start_date 
ORDER BY start_date ASC;

我无法将此原始查询转换为 Django ORM 查询。

如果有人可以提供一个示例 ORM 查询,有/没有使用 PostgreSQL 作为数据库后端的通用表表达式的解决方法。

原因很简单,引用here

我的偏好是在数据库中进行尽可能多的数据处理,而不是真正涉及的演示内容。我不羡慕在应用程序代码中这样做,只要它是一次访问数据库即可

根据this answer django 本身不支持 CTE,但答案似乎已经过时了。

参考资料:

谢谢

【问题讨论】:

标签: django postgresql django-queryset django-orm django-1.8


【解决方案1】:

我认为你不能用纯 Django ORM 做到这一点,我什至不确定这是否可以用 extra() 巧妙地完成。 Django ORM 在处理通常的东西方面非常出色,但是对于更复杂的 SQL 语句和要求,尤其是 DBMS 特定的实现,它还没有完全实现。您可能不得不降低到executing raw SQL directly,或者卸载由应用程序层完成的要求。

您始终可以使用 Python 生成缺失的日期,但如果元素的范围和数量很大,那将非常缓慢。如果 AJAX 要求将其用于其他用途(例如图表),那么您可以将其卸载到 Javascript。

【讨论】:

    【解决方案2】:

    您可以使用generate_series() 来构造日历表,而不是递归 CTE:

    SELECT calendar, count(mt.zdate) as THE_COUNT
    FROM generate_series('2015-07-20'::date
                       , '2015-07-24'::date
                       , '1 day'::interval)  calendar
    LEFT JOIN my_table mt ON mt.zdate = calendar
    GROUP BY 1
    ORDER BY 1 ASC;
    

    顺便说一句:我将date 重命名为zdate。 DATE 是列的错误名称(它是数据类型的名称)

    【讨论】:

      猜你喜欢
      • 2011-04-02
      • 2021-03-19
      • 1970-01-01
      • 1970-01-01
      • 2020-01-13
      • 1970-01-01
      • 2023-03-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多