[Django / python] 関連テーブルの複数の属性を条件にしてgroup_byする(ORMで)
やりたいこと
- 複数のテーブルを結合し、その結果できた表に対して
GROUP_BY
、SUM
を適用したい。
-
GROUP_BY
の条件とするのは、関連テーブル側に存在するカラム。
どういうこと?
GROUP_BY
、SUM
を適用したい。GROUP_BY
の条件とするのは、関連テーブル側に存在するカラム。以下のようなテーブルがあると考えます。
テーブル
1. Orders(注文)
カラム名 | 型 |
---|---|
id | integer |
date | date |
2. Items(商品)
カラム名 | 型 |
---|---|
id | integer |
name | string |
3. OrderedItems(注文された商品)
カラム名 | 型 |
---|---|
id | integer |
order_id | integer |
item_id | integer |
count | integer |
このようなテーブルがあるとして、それぞれの日(date)にどの商品(name)がどれだけ(count)注文されたのかを集計したい。
そこで次のようなSQLが思い浮かぶ....
SQL
※このSQLは実際に実行したわけではないので、このSQLには誤りが含まれている可能性がかなり高いです。
あくまでもイメージです。
SELECT orders.date,
items.name,
SUM(ordered_items.count) AS total
FROM ordered_items
LEFT JOIN orders ON ordered_items.order_id = orders.id
LEFT JOIN items ON ordered_items.item_id = items.id
GROUP BY orders.date, items.name;
こんな感じのSQLをDjango
のORM経由で実行したい。
これでできた 1
python
from django.db.models import Sum
OrderedItem.objects \
.values('order__date', 'item__name') \
.annotate(total=Sum('count'))
ポイント?
from django.db.models import Sum
OrderedItem.objects \
.values('order__date', 'item__name') \
.annotate(total=Sum('count'))
どうやら、
- GROUP_BYしたいとき
values
メソッドの引数に、GROUP_BYする際の条件とするカラム名を文字列で指定する - 他のテーブルのカラムを条件にしてGROUP_BYしたい場合
values
に指定するカラム名の前に、{テーブル名}__
をつける
=>'{テーブル名}__{カラム名}'
のようになる - 複数条件で
GROUP_BY
したい場合
values
メソッドの引数として、それらの条件を全て列挙する
で良さそう。
感想
このあたりの情報をはっきりと記載している記事がなかなか見つからなかった、、、
特にポイントの3つ目については、記載されている記事を見つけられず、仕方なく勧で書いたらたまたま動いてしまった、という状況でした...ԅ(º﹃ºԅ)
そんなわけでメモ化。
(次回スムーズに同じことができる自信がない...)
参考にした記事
より役に立ったと感じた順に記載しています
そしてなぜDjangoの公式サイトがヒットしない......?
公式サイトが全然頼りにならない...
-
実際には、もっとわけのわからない名前のテーブルに対してこの処理実行しており、今回はわかりやすくするためにテーブル名やカラム名を変えているので、完全にこの通りに書いても動かない可能性もあります。 ↩
Author And Source
この問題について([Django / python] 関連テーブルの複数の属性を条件にしてgroup_byする(ORMで)), 我々は、より多くの情報をここで見つけました https://qiita.com/siruku6/items/a6cab6c3dfa10c0bfed2著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .