Django GROUP BY strftime формат даты - PullRequest
14 голосов
/ 06 апреля 2009

Я хотел бы сделать СУММ для строк в базе данных и сгруппировать по дате.

Я пытаюсь выполнить этот SQL-запрос, используя агрегаты и аннотации Django:

select strftime('%m/%d/%Y', time_stamp) as the_date, sum(numbers_data)
    from my_model
    group by the_date;

Я попробовал следующее:

data = My_Model.objects.values("strftime('%m/%d/%Y',
           time_stamp)").annotate(Sum("numbers_data")).order_by()

но похоже, что вы можете использовать только имена столбцов в функции values ​​(); ему не нравится использование strftime ().

Как мне поступить об этом?

Ответы [ 5 ]

15 голосов
/ 06 апреля 2009

Это работает для меня:

select_data = {"d": """strftime('%%m/%%d/%%Y', time_stamp)"""}

data = My_Model.objects.extra(select=select_data).values('d').annotate(Sum("numbers_data")).order_by()

Потребовалось немного, чтобы понять, что я должен был избежать знаков%.

4 голосов
/ 09 июля 2016

Начиная с v1.8, вы можете использовать выражения Func () .

Например, если вы нацелены на функции даты и времени AWS Redshift:

from django.db.models import F, Func, Value

def TimezoneConvertedDateF(field_name, tz_name):
    tz_fn = Func(Value(tz_name), F(field_name), function='CONVERT_TIMEZONE')
    dt_fn = Func(tz_fn, function='TRUNC')
    return dt_fn

Тогда вы можете использовать это так:

SomeDbModel.objects \
 .annotate(the_date=TimezoneConvertedDateF('some_timestamp_col_name',
                                           'America/New_York')) \
 .filter(the_date=...)

или как это:

SomeDbModel.objects \
 .annotate(the_date=TimezoneConvertedDateF('some_timestamp_col_name',
                                           'America/New_York')) \
 .values('the_date') \
 .annotate(...)
1 голос
/ 17 марта 2016

Я не уверен насчет strftime, мое решение ниже использует sql postgres trunc ...

select_data = {"date": "date_trunc('day', creationtime)"}       
ttl = ReportWebclick.objects.using('cms')\
                    .extra(select=select_data)\
                    .filter(**filters)\
                    .values('date', 'tone_name', 'singer', 'parthner', 'price', 'period')\
                    .annotate(loadcount=Sum('loadcount'), buycount=Sum('buycount'), cancelcount=Sum('cancelcount'))\
                    .order_by('date', 'parthner')

- равно выполнению SQL-запроса:

select date_trunc('month', creationtime) as date, tone_name, sum(loadcount), sum(buycount), sum(cancelcount)
from webclickstat
group by tone_name, date;
1 голос
/ 06 апреля 2009

Любая причина не просто сделать это в базе данных, выполнив следующий запрос к базе данных:

select date, sum(numbers_data) 
from my_model 
group by date;

Если ваш ответ: дата - это дата-время с ненулевыми часами, минутами, секундами или миллисекундами, мой ответ - использовать функцию даты для усечения даты-времени, но я не могу точно сказать, что это не зная, какую RBDMS вы используете.

0 голосов
/ 10 апреля 2018

мое решение, как это, когда мой БД MySQL:

select_data = {"date":"""FROM_UNIXTIME( action_time,'%%Y-%%m-%%d')"""} 
qs = ViewLogs.objects.filter().extra(select=select_data).values('mall_id', 'date').annotate(pv=Count('id'), uv=Count('visitor_id', distinct=True))

, чтобы использовать какую функцию, вы можете прочитать документацию по процессору даты и времени mysql, такую ​​как DATE_FORMAT, FROM_UNIXTIME ...

...