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)
これを単純化して、通貨が 1 つしかなく、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 |
+---------------------+-------------------+------------+------------+---------------+
これは数学演算を単純化するための例であることに注意してください!
このテーブルでは、データ密度は月に 1 回で、1 か月の有効なレコードは、たとえば、いつ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
2 つの日付の間の月を計算する関数ですmonths_between()
greater
、smaller
引数からそれに応じて大きい値と小さい値を選択する関数です -greatest()
、least()
ER
からの列を意味しますExchangeRate
-例F('exchange_rate')
私は9.3 PostgreSQL DBとDjango 1.8.4を使用しています。
多分そのための簡単な機能がありますか?
多分私はこれを過度に複雑にしていますか?