ホームページ  >  記事  >  バックエンド開発  >  Django orm で group by に annotate を使用する

Django orm で group by に annotate を使用する

高洛峰
高洛峰オリジナル
2016-11-23 09:43:043417ブラウズ

使用法

Django 1.8 では、以前の ORM グループ化メソッドは使用できなくなりました。 annotate を使用して実装する必要があります

例 1

最初の値は、グループに使用する必要があるフィールドを選択するために使用されます。 by (ここでは user_id でグループ化)、続いて必須フィールドをグループ化して集計するために注釈を付けます (各 user_id に対応する question_id の数と、catalog_id の最小値が必要です)。次に、必須フィールドを実際にクエリするための値 (エイリアス)元の user_id と集計フィールドの)

最初の値は、グループ化に使用するフィールドを指定するために使用されます。これは、Count や Min などの集計関数である必要があります (たとえば、F ("user_id") を使用して取得します)エイリアスは機能しません)。最終的なクエリが必要ない場合は、集計する必要はありません。

2 番目の値は、アノテーションの後のフィールド名のみを指定できます。例として: user_id はグループ化に使用されるフィールドであり、直接取得できますが、他のフィールドは集計し、エイリアス、qid、cid を使用して集計する必要があります。元のテーブルにもフィールド ステータスがある場合、このフィールドは集計されません。注釈を付けるため、このフィールドの最終値をクエリすることはできません)

q = PxbNCEUserQuest.objects.filter(user_id=335).values("user_id").annotate(qid=Min("question_id"), cid=Min("catalog_id")).values("user_id", "qid", "cid")
print q
print q.query

# 输出
[{'qid': 22, 'user_id': 335L, 'cid': 17}]

SELECT `pxb_nce_user_quest`.`user_id`, MIN(`pxb_nce_user_quest`.`question_id`) AS `qid`, MIN(`pxb_nce_user_quest`.`catalog_id`) AS `cid` FROM `pxb_nce_user_quest` WHERE `pxb_nce_user_quest`.`user_id` = 335 GROUP BY `pxb_nce_user_quest`.`user_id` ORDER BY NULL

例 2

例 1 と同じですが、最初の注釈はフィールドをグループ化するために使用され、2 番目の注釈は他のフィールドを個別にエイリアスするために使用されます

q = PxbNCEUserQuest.objects.filter(user_id=335).values("user_id").annotate(qid=Min("question_id"), cid=Min("catalog_id")).annotate(uid=F("user_id")).values("uid", "qid", "cid")
print q
print q.query
# 输出:
[{'qid': 22, 'uid': 335L, 'cid': 17}]

SELECT MIN(`pxb_nce_user_quest`.`question_id`) AS `qid`, MIN(`pxb_nce_user_quest`.`catalog_id`) AS `cid`, `pxb_nce_user_quest`.`user_id` AS `uid` FROM `pxb_nce_user_quest` WHERE `pxb_nce_user_quest`.`user_id` = 335 GROUP BY `pxb_nce_user_quest`.`user_id` ORDER BY NULL

例:

SomeModel.objects.annotate(Count('somecol'))

GROUP BY: すべてのフィールド

SomeModel.objects.values ('name').annotate(Count('somecol'))

GROUP BY: 名前フィールド、集計 somecol

SomeModel.objects.annotate(Count('somecol')).values('name')

GROUP BY: すべてのフィールド、クエリ名

SomeModel.objects.values('name ', 'pk').annotate(Count('somecol')).values('pk')

GROUP BY: name, pk フィールド、pk フィールドをクエリします

SomeModel.objects.values('name')。 annotate(Count('somecol')).values('pk')

GROUP BY: name, pk field, query the pk field

関連知識:

上記のクエリメソッドは最初は理解しにくいかもしれませんが、元の SQL ステートメントの group by メソッドを比較すると、同様の原理がわかります

古いバージョンの mysql では、

select a, b from t group by a は正常に機能し、b フィールドの最初の項目これは、暗黙的な集計と同等であり、厳密モード sql_mode=ONLY_FULL_GROUP_BY がデフォルトで有効になっているため、上記のステートメントは機能しません。

select a,max(b) as b from t group by、つまりすべてのクエリを集約するために表示する必要があるフィールドです

新しいバージョンの mysql 構文を比較すると、ORM のクエリメソッドと非常によく似ていることがわかります

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。