查詢複雜要值的簡單表格獲得最大的價值,我可以寫在Django以下查詢:主鍵要求在Django
MyTable.objects.aggregate(Max('value'))
生成的SQL是:'SELECT MAX("mytable"."value") AS "value__max" FROM "mytable"'
現在,如果我寫使用原始查詢管理器相同的SQL:
1. MyTable.objects.raw('SELECT max(value) FROM mytable')
的Django引發錯誤InvalidQuery: Raw query must include the primary key
。 Django文檔中也提到了這一點:「只有一個字段不能被忽略 - 主鍵字段」。所以在添加id
字段後,我也需要GROUP BY
。新的查詢變爲:
2. MyTable.objects.raw('SELECT id, max(value) FROM mytable GROUP BY id')
這已經不給我一個最大值,因爲我被迫使用GROUP BY id
。現在我需要添加一個ORDER BY
和LIMIT
語句來獲得適用於其他簡單的SQL語句的預期答案。
3. MyTable.objects.raw('SELECT id, max(value) AS mv FROM mytable GROUP BY id ORDER BY mv DESC LIMIT 1')
有沒有辦法簡化上面的查詢,即不使用ORDER/LIMIT/GROUP BY(FWIW,使用PosgreSQL)?
更新:
下面是會工作黑客攻擊。我將最大值別名爲id
,以使Django高興。這裏有什麼問題嗎?
MyTable.objects.raw('SELECT max(value) AS id FROM mytable')
更新2:
這裏有一個簡單的SQL(1)VS複雜的最後一個(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"
PS的實際查詢更爲複雜(有點與此相關的答案:https://dba.stackexchange.com/a/86404/52114)
'GRO UP BY'(沒有任何其他表加入)違背了彙總值的目的(即在你的例子中'max(value)'將只從最大值中選擇1個值) - 'SELECT max(value)FROM mytable GROUP BY id LIMIT 1'與'SELECT max(value)FROM mytable'不一樣 –
pozs
2014-12-19 10:00:59
你錯過了'ORDER BY'子句。 1)&3)應該給出相同的結果,如果有一個單一的最大值。如果超過1,則需要添加id或其他內容以使訂單可預測。 – user4150760 2014-12-19 12:30:43
順序無關緊要(它只能使您的查詢可預測); 1)&3)不應該給你一般的結果,只有在特殊情況下:http://sqlfiddle.com/#!15/ceb1d/2 - 你也可以使用ORDER BY值DESC LIMIT 1'找到最大值,但在這種情況下,根本不需要聚合。 – pozs 2014-12-19 12:41:45