【发布时间】:2015-11-27 20:18:48
【问题描述】:
在 Django 中,我有类似于此示例的模型:
class Currency(models.Model):
name = models.CharField(max_length=3, unique=True)
full_name = models.CharField(max_length=20)
class ExchangeRate(models.Model):
currency = models.ForeignKey('Currency')
start_date = models.DateFiled()
end_date = models.DateField()
exchange_rate = models.DecimalField(max_digits=12, decimal_places=4)
让我们简化一下,假设我们只有一种货币,ExchangeRate 表如下所示:
+---------------------+-------------------+------------+------------+---------------+
| currency_from__name | currency_to__name | start_date | end_date | exchange_rate |
+---------------------+-------------------+------------+------------+---------------+
| PLN | USD | 2014-03-01 | 2014-08-01 | 3.00000 |
| PLN | USD | 2014-08-01 | 2014-12-01 | 6.00000 |
+---------------------+-------------------+------------+------------+---------------+
请注意这是简化数学运算的示例!
此表中的数据密度为每月一次,一个月的有效记录例如start_date = 2014.03.01和end_date = 2014.04.01,所以start_date是包含的,end_date是排除的。
我想计算时间段的平均汇率:
当我在 Django 中写作时:
start_date = date(2014, 6, 1)
end_date = date(2014, 9, 1)
ExchangeRate.objects.all().filter(
(
Q(start_date__lt=start_date) &
Q(end_date__gt=start_date)
) | (
Q(start_date__gte=start_date) &
Q(start_date__lt=end_date) &
Q(end_date__gt=start_date)
)
).annotate(
currency_from_name = 'currency_from__name',
currency_to_name = 'currency_to__name'
).values( # GROUP BY
'currency_from_name',
'currency_to_name'
).aggregate(
F('currency_from_name'),
F('currency_to_name'),
Avg('exchange_rate')
)
在此查询之后,我收到了值 4.5000,从数学上看它是正确的,但当您需要注意时间范围时是错误的。
正确答案是4.000。
我只是想出了这个解决方案,用这个公式注释额外的列,然后从这个列计算平均值:
地点:
-
Abs是绝对值函数abs() -
months是计算两个日期之间月份的函数months_between() -
greater,smaller是从参数中选择相应更大和更小的值的函数 -greatest(),least() -
ER表示来自ExchangeRate的列 - 例如F('exchange_rate')
我正在使用 9.3 PostgreSQL DB 和 Django 1.8.4。
也许有一个简单的功能?
也许我把这件事复杂化了?
【问题讨论】:
-
您为什么不想在 Python 中执行此操作?那张桌子大吗?
-
这个 必须 在数据库端计算,如果我必须创建
months_between函数,我也可以简单地创建这个average_weight但这也可以在 Django QuerySet 方式中完成 -
@PabTorre "
start_date是包容性的,end_date是独占性的。" 所以6:) -
明白了。这解释了。 :) 我更新了我的答案。
标签: django postgresql django-models django-queryset django-aggregation