为了从简单的值表中获取最大值,我可以在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
docs中也提到了这一点:“您只能忽略一个字段-主键字段”。因此,添加id
字段后,我也需要GROUP BY
。新查询变为:
2. MyTable.objects.raw('SELECT id, max(value) FROM mytable GROUP BY id')
这不再给我一个最大值,因为我被迫使用GROUP BY id
。现在,我需要添加ORDER BY
andLIMIT
语句,以获取可以正常工作的否则简单的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)与复杂的最后一个(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)
您应该使用自定义SQL而不是Manager.raw()
方法:
from django.db import connection
cursor = connection.cursor()
cursor.execute('SELECT max(value) FROM mytable')
max_value = cursor.fetchone()[0]
在模型查询API不够用的情况下,你可以使用原始的sql语句。django提供两种方法使用原始sql进行查询:一种是使用Manager.raw()方法,进行原始查询并返回模型实例;另一种是完全避开模型层,直接执行自定义的sql语句。 警告 编写原始的sql语句时,应该格外小心。每次使用的时候,都要确保转义了参数中的任何控制字符,以防受到sql注入攻击。更多信息请参阅防止sql注入。 进行原始查询 r
在用户模型中,我定义了关系: 它返回如何获得包括参数的完整查询? 我还定义了与post模型的关系: 如何使用参数查看完整的关系查询?
问题内容: 我有一个具有复合主键的旧式数据库表。我认为我无法更改结构以包含代理键,因为编写了一些使用该表的代码。在django中,我无法使用该表,因为它没有主键(非复合键)。 Django模型是否支持复合主键?如果不是,是否有任何解决方法而不更改表的结构? PS我正在使用PostgreSQL。 问题答案: 试试下面类似的代码: 或者,如果你只想要唯一的混合字段: 编辑:我想指出,如果有3列,则此方
问题内容: 我正在将MS-Access 2003与查询创建者一起使用。我从一个表()中选择所有内容,然后从另一表()中选择一个特定行()。我想从第二个表中选择另一行并将其连接起来。 查询 该查询的确在ID(字段)与where匹配的地方添加了字段。它像一种魅力。但是,我想在结果中添加另一行。我想获得行所在的位置(该部分实际上在工作)和行所在的位置。我将得到2行,并且当我要求()时,我希望将这两行连接
问题内容: 有没有一种方法可以显示执行查询时Django正在运行的SQL? 问题答案: 请参阅文档FAQ:“如何查看Django正在运行的原始SQL查询? ” 包含SQL查询的列表: 查询集还具有包含要执行的查询的属性: 请注意,查询的输出不是有效的SQL,因为: “ Django实际上从未插值参数:它将查询和参数分别发送到数据库适配器,后者执行适当的操作。” 来自Django错误报告#17741
问题内容: 我正在尝试使用类似于以下内容的原始sql查询 但是,这似乎在自己的单独事务中运行。因此,它会错过在service方法中之前完成的所有(未提交的)更改。 在当前事务中运行原始sql查询的最佳方法是什么? 问题答案: 上面的代码将创建一个新的连接,从而创建一个新的事务。您可以使用当前的Hibernate会话(注入sessionFactory)在当前事务中执行原始sql,如下所示。