Django - 分组依据,按日期范围分割
Django - Group by, split by date range
我有一个模型:
class MyModel(models.Model):
store_id = models.TextField()
day_dt = models.DateField()
param1 = models.IntegerField()
param2 = models.IntegerField()
一些数据示例:
store_id | day_dt | param1 | param2
----------------------------------------
STORE1 | 2021-09-30 | 10 | 30
STORE2 | 2021-09-31 | 20 | 40
....
STORE1 | 2021-10-01 | 4 | 5
STORE1 | 2021-10-02 | 6 | 10
STORE1 | 2021-10-03 | 2 | 5
STORE2 | 2021-10-02 | 3 | 7
STORE2 | 2021-10-03 | 1 | 19
....
我需要按 store_id
和间隔(day_dt
应该在 2021-10-01
和 2021-10-04
之间)对数据进行分组:
STORE1 | 2021-10-01
STORE1 | 2021-10-02
STORE1 | 2021-10-03
和
STORE2 | 2021-10-02
STORE2 | 2021-10-03
然后应用于每个(两个)组聚合:Avg('param1') 和 Avg('param2').
数据示例的预期输出:
store_id | param1_avg | param2_avg
----------------------------------
STORE1 | 6 | 10
STORE2 | 2 | 13
如何使用 ORM 进行聚合?
您可以通过以下方式实现:
from django.db.models import Avg
MyModel.objects<strong>.filter(</strong>
date_dt__range=('2021-10-01', '2021-10-04')
<strong>).values(</strong>'store_id'<strong>).annotate(</strong>
param1_avg=Avg('param1'),
param2_avg=Avg('param2')
<strong>).order_by(</strong>'store_id'<strong>)</strong>
这将 return 一个 QuerySet
字典,看起来像:
<QuerySet [
{'store_id': 'STORE1', param1_avg: 6, param2_avg: 10},
{'store_id': 'STORE2', param1_avg: 2, param2_avg: 13}
]>
在给定日期范围内没有 MyModel
记录的商店将 不会 在生成的查询集中有字典对象。
您可以使用,这是最简单的方法。
但是 Django 解决方案使用的是 Expression 和 writing your own Query Expressions。在此解决方案中,您创建了一个类似于 Hours
的表达式,并在 annotate
函数中使用它,例如:.annotate(Hours("day_dt"))
。您应该覆盖 as_sql
函数来编写自定义 SQL 方法,或者覆盖 as_sqlite
和 as_postgresql
函数以支持不同的 DBMS。
我有一个模型:
class MyModel(models.Model):
store_id = models.TextField()
day_dt = models.DateField()
param1 = models.IntegerField()
param2 = models.IntegerField()
一些数据示例:
store_id | day_dt | param1 | param2
----------------------------------------
STORE1 | 2021-09-30 | 10 | 30
STORE2 | 2021-09-31 | 20 | 40
....
STORE1 | 2021-10-01 | 4 | 5
STORE1 | 2021-10-02 | 6 | 10
STORE1 | 2021-10-03 | 2 | 5
STORE2 | 2021-10-02 | 3 | 7
STORE2 | 2021-10-03 | 1 | 19
....
我需要按 store_id
和间隔(day_dt
应该在 2021-10-01
和 2021-10-04
之间)对数据进行分组:
STORE1 | 2021-10-01
STORE1 | 2021-10-02
STORE1 | 2021-10-03
和
STORE2 | 2021-10-02
STORE2 | 2021-10-03
然后应用于每个(两个)组聚合:Avg('param1') 和 Avg('param2').
数据示例的预期输出:
store_id | param1_avg | param2_avg
----------------------------------
STORE1 | 6 | 10
STORE2 | 2 | 13
如何使用 ORM 进行聚合?
您可以通过以下方式实现:
from django.db.models import Avg
MyModel.objects<strong>.filter(</strong>
date_dt__range=('2021-10-01', '2021-10-04')
<strong>).values(</strong>'store_id'<strong>).annotate(</strong>
param1_avg=Avg('param1'),
param2_avg=Avg('param2')
<strong>).order_by(</strong>'store_id'<strong>)</strong>
这将 return 一个 QuerySet
字典,看起来像:
<QuerySet [
{'store_id': 'STORE1', param1_avg: 6, param2_avg: 10},
{'store_id': 'STORE2', param1_avg: 2, param2_avg: 13}
]>
在给定日期范围内没有 MyModel
记录的商店将 不会 在生成的查询集中有字典对象。
您可以使用
但是 Django 解决方案使用的是 Expression 和 writing your own Query Expressions。在此解决方案中,您创建了一个类似于 Hours
的表达式,并在 annotate
函数中使用它,例如:.annotate(Hours("day_dt"))
。您应该覆盖 as_sql
函数来编写自定义 SQL 方法,或者覆盖 as_sqlite
和 as_postgresql
函数以支持不同的 DBMS。