Как сделать aggregate raw sql с юлианской датой в sqlite (с помощью django)
Я использую sqlite3 и django. Я хочу вычислить среднее значение для всех дней между last_played и now. (Last_played - это просто поле времени даты).
У меня на данный момент:
avg_days_last_played_sql = """
AVG(julianday('now') - julianday(played_at))
"""
# Annotate the average days last played
average_days_last_played = Song.objects.aggregate(
avg_days_last_played=RawSQL(avg_days_last_played_sql, [])
)['avg_days_last_played']
Но он выдает ошибку:
TypeError: avg_days_last_played не является агрегированным выражением
Я не думаю, что для этого нужен собственный сырой запрос. Мы можем работать с:
from django.db.models import FloatField
from django.db.models.expressions import Func
class JulianDay(Func):
function = 'julianday'
output_field = FloatField()
и затем работайте с:
from django.db.models import Avg, F
from django.db.models.functions import Now
Song.objects.aggregate(
avg_days_last_played=Avg(JulianDay(Now()) - JulianDay(F('played_at')))
)['avg_days_last_played']
Теперь мы можем использовать функцию JulianDay
во всех других выражениях, тем самым не только решив эту проблему, но и сделав более удобным решение смежных задач.
При этом хранение played_at
в песне выглядит странно, обычно вы создаете отдельную модель, которая хранит для каждой песни, когда она была проиграна, чтобы вы могли выполнять дополнительную фильтрацию, агрегирование и т.д.