Primärschlüsselanforderung in Raw SQL erschwert die Abfrage in Django

Um den maximalen Wert aus einer einfachen Wertetabelle zu erhalten, kann ich die folgende Abfrage in Django schreiben:

MyTable.objects.aggregate(Max('value'))

Die generierte SQL ist:'SELECT MAX("mytable"."value") AS "value__max" FROM "mytable"'

Nun, wenn ich dieselbe SQL mit dem Raw-Abfrage-Manager schreibe:

1. MyTable.objects.raw('SELECT max(value) FROM mytable')

Django wirft einen FehlerInvalidQuery: Raw query must include the primary key. Dies wird auch in Django-Dokumenten erwähnt: "Es gibt nur ein Feld, das Sie nicht auslassen dürfen - das Primärschlüsselfeld". Also nach dem Hinzufügen desid field, ich braucheGROUP BY auch. Die neue Abfrage lautet:

2. MyTable.objects.raw('SELECT id, max(value) FROM mytable GROUP BY id')

Dies gibt mir keinen einzigen Maximalwert mehr, weil ich gezwungen bin, @ zu verwendeGROUP BY id. Jetzt muss ich ein @ hinzufügORDER BY undLIMIT Anweisung, um die erwartete Antwort für eine ansonsten einfache SQL-Anweisung zu erhalten, die funktioniert.

3. MyTable.objects.raw('SELECT id, max(value) AS mv FROM mytable GROUP BY id ORDER BY mv DESC LIMIT 1')

Gibt es eine Möglichkeit, die obige Abfrage zu vereinfachen, d. H. ORDER / LIMIT / GROUP BY (FWIW, PosgreSQL) nicht zu verwenden?

Aktualisieren

Hier ist ein Hack, der funktionieren wird. Ich alias der Maximalwert alsid um Django glücklich zu machen. Gibt es hier ein Problem?

MyTable.objects.raw('SELECT max(value) AS id FROM mytable')

Update 2:

Hier ist der Abfrageplan für das einfache SQL (1) im Vergleich zum komplizierten endgültigen SQL (3):

"Aggregate  (cost=5.25..5.26 rows=1 width=2) (actual time=0.155..0.155 rows=1 loops=1)"
"  ->  Seq Scan on mytable  (cost=0.00..4.60 rows=260 width=2) (actual time=0.018..0.067 rows=260 loops=1)"
"Total runtime: 0.222 ms"


"Limit  (cost=9.80..9.80 rows=1 width=6) (actual time=0.548..0.548 rows=1 loops=1)"
"  ->  Sort  (cost=9.80..10.45 rows=260 width=6) (actual time=0.545..0.545 rows=1 loops=1)"
"        Sort Key: (max(value))"
"        Sort Method: top-N heapsort  Memory: 25kB"
"        ->  HashAggregate  (cost=5.90..8.50 rows=260 width=6) (actual time=0.328..0.432 rows=260 loops=1)"
"              ->  Seq Scan on mytable  (cost=0.00..4.60 rows=260 width=6) (actual time=0.018..0.069 rows=260 loops=1)"
"Total runtime: 0.638 ms"

P.S. Die eigentliche Abfrage ist komplizierter (etwas im Zusammenhang mit dieser Antwort:https: //dba.stackexchange.com/a/86404/5211)

Antworten auf die Frage(6)

Ihre Antwort auf die Frage