Aggregationを使う - Annotate編

前提として

Django 1.1pre(revision 9742)以降から使える機能です。

Annotateとは

QuerySetを指定したフィールドでグループ化します。
SQLでいうところの"GROUP BY句"です。

model作成

from django.db import models

class Account(models.Model):
    name = models.CharField(max_length = 10)
    cash = models.IntegerField()
    payment_day = models.DateField()

Annotateを試してみる

今回もshellモードで確認します。

manage.py shell

下準備

>>>from appname.models import Plan, Account
>>>from django.db.models import Avg, Max, Min, Sum, Count
>>>Account.objects.create(name = 'Bob', cash = 100, payment_day = '2009-04-01')
>>>Account.objects.create(name = 'Jon', cash = 75, payment_day = '2009-04-02')
>>>Account.objects.create(name = 'Ted', cash = 34, payment_day = '2009-04-01')

日付でグループ化した支払い件数の取得

>>>Account.objects.values('payment_day').annotate(counter = Count('payment_day'))
[{'counter': 2, 'payment_day': u'2009-04-01'}, 
{'counter': 1, 'payment_day': u'2009-04-02'}]

日付でグループ化した支払い金額を取得

>>>Account.objects.values('payment_day').annotate(Sum = Sum('cash'))
[{'Sum': 134, 'payment_day': u'2009-04-01'}, 
{'Sum': 75, 'payment_day': u'2009-04-02'}]

日付でグループ化した支払い金額の最大と最小額を取得

>>>Account.objects.values('payment_day').annotate(Max = Max('cash'), Min = Min('cash'))
[{'Max': 100, 'payment_day': u'2009-04-01', 'Min': 34}, 
{'Max': 75, 'payment_day': u'2009-04-02', 'Min': 75}]

名前でグループ化した支払い金額の合計を取得

>>>Account.objects.create(name = 'Bob', cash = 15, payment_day = '2009-05-01')
>>>Account.objects.values('name').annotate(Sum = Sum('cash'))
[{'Sum': 115, 'name': u'Bob'}, 
{'Sum': 75, 'name': u'Jon'}, 
{'Sum': 34, 'name': u'Ted'}]

日付、名前でグループ化して、合計金額を取得

>>>Account.objects.create(name = 'Ted', cash = 89, payment_day = '2009-04-01')
>>>Account.objects.values('payment_day', 'name').annotate(Sum = Sum('cash'))
[{'Sum': 100, 'name': u'Bob', 'payment_day': u'2009-04-01'}, 
{'Sum': 123, 'name': u'Ted', 'payment_day': u'2009-04-01'}, 
{'Sum': 75, 'name': u'Jon', 'payment_day': u'2009-04-02'}, 
{'Sum': 15, 'name': u'Bob', 'payment_day': u'2009-05-01'}]

filter()やorder_by()、exclude()と組み合わせて取得することも可能です。

twitter 2009-04-14 15:57:37.662533

関連ページ

Recent Updates

URLConf Tip 01 - キャプチャの有無にかかわらず同一のviewで処理する
Markdownの入力補助"wmd"をAdmin siteで使う
ModelFormでfieldのwidgetを変更する
動的なformを作る 6 - Dynamic Inline Admin site編
Formsetsを使う3 - inlineformset_factory編
動的なformを作る 5 - django-dynamic-formset編
Formクラスからメディアを定義する
複数のmodelを結合する 2 - Proxy model編
複数のmodelを結合する 1
ModelFormでfieldの表示順番を変える
Admin siteのwidgetを個別に変更する
formfield_overridesを使ってAdmin siteのwidgetを変更する
Admin siteのlist_displayをカスタマイズする - リンク編
Admin siteのlist_displayをカスタマイズする - 基本編
Admin siteのTextareaの高さを自在に変更する - admin.py編