このような非常に単純なモデルがあるとしましょう。
class Test(models.Model):
category = models.CharField(unique=True)
start_time = models.DateTimeField()
end_time = models.DateTimeField()
基本的に、DjangoのORM APIを使用して、カテゴリごとの平均期間を取得したいと思います。SQLクエリは次のようになります。
SELECT category, AVG(end_time - start_time) AS avg_duration
FROM test_table
GROUP BY category
次のコードを使用してみましたが、ドキュメントによると、.annotate()のF()式はDjano1.8でのみ使用できます。
Test.objects.values('category', 'start_time', 'end_time').annotate(avg_duration=Avg(F(end_time) - F(start_time))
このように.extra()も使用してみましたが、FieldErrorが発生します。
Test.objects.extra(select={'duration':'end_time - start_time'}).values('category', 'duration').annotate(avg_duration=Avg('duration'))
見た目から、2回目の試行は、注釈関数が列エイリアスを解決できないことを示唆しています。これは本当に本当ですか、それとも私は何かが足りないのですか?
さらに、派生情報(エントリごとの期間)を格納する追加の列を作成したり、Django 1.8を使用したり、生のSQLを使用したりする以外に、他にどのような代替案をお勧めできますか?どんな助けでも大歓迎です。ありがとう!
これを試して:
Test.objects.values('category').extra(select={'avg_duration':'AVG(end_time - start_time)'})
うん、それは起こらない、なぜなら
values()呼び出しの後に行われたextra()呼び出しでは、余分に選択されたフィールドは無視されます。
:.values()
に含める必要があるため、以前は使用できません.values()
。
extra()呼び出しの後にvalues()句を使用する場合、extra()のselect引数で定義されたフィールドは、values()呼び出しに明示的に含める必要があります。
したがって、このようにして、すべての.extra
選択がグループ化に含まれます。
でも、そういうものがないと作れAvg
ない.extra
ので、残った解決策は使うことだけだと思います.raw
Test.objects.raw('\
SELECT id, category, AVG(end_time - start_time) AS avg_duration \
FROM test_table \
GROUP BY category'
)
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加