Heim  >  Artikel  >  Backend-Entwicklung  >  Verwenden von Annotate für Group by in Django Orm

Verwenden von Annotate für Group by in Django Orm

高洛峰
高洛峰Original
2016-11-23 09:43:043470Durchsuche

Verwendung

Die Methode „Gruppe nach“ des vorherigen ORM kann in Django 1.8 nicht mehr verwendet werden und Sie müssen annotate verwenden, um sie zu implementieren

Beispiel 1

Die ersten Werte werden verwendet. Wählen Sie die Felder aus, die gruppiert werden müssen (hier gruppieren Sie nach Benutzer-ID), und folgen Sie dann Annotate, um die erforderlichen Felder zu gruppieren und zu aggregieren (die Anzahl der Frage-IDs, die jeder Benutzer-ID entsprechen, und der Mindestwert von Katalog-ID sind erforderlich). ) und verwenden Sie dann Werte, um tatsächlich erforderliche Felder (Aliase der ursprünglichen Benutzer-ID und der aggregierten Felder) abzufragen.

Die ersten Werte werden verwendet, um die Felder anzugeben, die für die Gruppierung nach verwendet werden. Diese müssen Anzahl, Min. sein und andere Aggregatfunktionen (z. B. ist die Verwendung von F(" user_id")-Aliasing nicht möglich), ist keine Aggregation erforderlich, wenn Sie die endgültige Abfrage nicht benötigen

Der zweite Wert wird verwendet um das tatsächlich ausgewählte Feld anzugeben, und kann nur den Feldnamen nach der Annotation angeben (hier ist beispielsweise: user_id ist ein Feld, das zur Gruppierung verwendet wird und direkt übernommen werden kann, während andere Felder aggregiert werden müssen und die aggregierten Aliase qid und cid verwenden müssen . Wenn die Originaltabelle auch einen Feldstatus hat, wird dieses Feld nicht in Annotate aggregiert, sodass der Endwert das Feld nicht abfragen kann)

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

Beispiel 2

Wie Beispiel 1, aber hier wird die erste Anmerkung verwendet, um Felder zu gruppieren, und die zweite Anmerkung wird verwendet, um andere Felder einzeln mit einem Alias ​​zu versehen

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

Beispiel:

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

GROUP BY: alle Felder

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

GROUP BY: Namensfeld , aggregiere somecol

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

GROUP BY: Alle Felder, Abfragename

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

GROUP BY: Name, PK-Feld, Abfrage-PK-Feld

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

GROUP BY: Name, PK-Feld, Abfrage-PK-Feld

Zugehöriges Wissen:

Die obige Abfragemethode ist zunächst möglicherweise schwer zu verstehen, aber wenn Sie die Gruppe nach Methode der ursprünglichen SQL-Anweisung vergleichen, werden Sie ein ähnliches Prinzip finden

In der In der alten Version von MySQL

wählen Sie a, b aus der t-Gruppe nach a aus, funktioniert normal, und das b-Feld übernimmt automatisch das erste, was einer impliziten Aggregation entspricht

Die obige Aussage kann in der neuen Version von MySQL nicht funktionieren, da der strikte Modus sql_mode=ONLY_FULL_GROUP_BY standardmäßig aktiviert ist. Die richtige Methode ist:

select a,max(b) as b from t group by, the Felder, die angezeigt werden müssen, um alle Abfragen zusammenzufassen

Wenn Sie die neue Version der MySQL-Syntax vergleichen, werden Sie feststellen, dass sie der Abfragemethode in ORM sehr ähnlich ist


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn