查询复杂要值的简单表格获得最大的价值,我可以写在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