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()と組み合わせて取得することも可能です。