【发布时间】:2015-10-17 01:49:14
【问题描述】:
我正在编写一个复杂的 django 数据查询器并加快返回速度,我将values() 与 filter() 和聚合一起使用,但我遇到了一些重复结果的问题。
像这样描绘models.py:
class Person(models.Model):
name= CharField()
class Question(models.Model):
title = CharField()
date_asked = DateField()
asker = ForeignKey(person)
我想要做的是使用Person 查询集和values() 查询django 以获取一个人的姓名和他们最近的问题的标题。
如果我们有以下样本数据:
Person | Title | Date
----------------------------------------------
Jack | Where can I get water? | 2011-01-04
Jack | How to climb hill? | 2012-02-05
Jill | How to fix head injury? | 2014-03-06
我可以得到大部分的方法,像这样:
最近一个问题的人名和日期列表:
Person.objects.values('name','most_recent')\\
.annotate('most_recent'=Max('question__date_asked'))
Person | most_recent
--------------------
Jack | 2012-02-05
Jill | 2014-03-06
人名列表以及他们所有的问题和他们的头衔:
Person.objects.values('name','question__title','question__date_asked')
Person | Title | Date
----------------------------------------------
Jack | Where can I get water? | 2011-01-04
Jack | How to climb hill? | 2012-02-05
Jill | How to fix head injury? | 2014-03-06
但是当我尝试将它们放在一起时:
Person.objects.values('name','question__title','most_recent')\\
.annotate('most_recent'=Max('question__date_asked'))
.filt
Person | Title | most_recent
----------------------------------------------
Jack | Where can I get water? | 2011-01-04
Jack | How to climb hill? | 2012-02-05
Jill | How to fix head injury? | 2014-03-06
即使使用F() expression 也无法解决问题:
Person.objects.values('name','question__title','most_recent')\\
.annotate('most_recent'=Max('question__date_asked'))
.filter('question__date_asked'=F('most_recent'))
Person | Title | most_recent
----------------------------------------------
Jack | Where can I get water? | 2011-01-04
Jack | How to climb hill? | 2012-02-05
Jill | How to fix head injury? | 2014-03-06
注意:在上表中,给出了每个关系的“最大”日期,而不是每个人。
我需要的是:
Person | Title | most_recent
----------------------------------------------
Jack | How to climb hill? | 2012-02-05
Jill | How to fix head injury? | 2014-03-06
语句的顺序和连接意味着当同时使用过滤器、聚合和值时,连接发生在 SQL USING 语句之前,应该限制返回行.
关于如何执行此查询的任何想法?
更新:
相关的 SQL 查询如下所示:
SELECT "example_person"."full_name", "example_question"."title",
MAX("example_question"."date_asked") AS "max___example_question__date_asked"
FROM "example_person"
LEFT OUTER JOIN
"example_question" ON ( "example_person"."id" = "example_question"."person_id" )
INNER JOIN
"example_question" T3 ON ( "example_person"."id" = T3."person_id" )
GROUP BY
"example_person"."full_name", T3."start_date",
"example_person"."id", "example_question"."title"
HAVING
T3."date_asked" = (MAX("example_person"."date_asked"))
这个问题与 djangos 的 GROUP BY 语句的特异性有关。如果我运行 ./manage.py dbshell 并运行上面的查询,我会得到多余的结果,但如果我将其限制为 GROUP BY "example_person"."full_name" 而没有其他分组,我会得到正确的结果。
有没有办法限制 django 的 GROUP BY 或某种猴子补丁来限制它一点点?
【问题讨论】:
-
您是否尝试添加
distinct()? -
这里可以找到类似的问题,但是这些答案可能并不令人满意。这是一个棘手的问题。 stackoverflow.com/questions/31234880/…
-
@RetoAebersold
distinct不起作用,因为它返回不同的行 -
我看不出你的 Person 和 Question 模型之间有任何关系。
-
@BurhanKhalid eek... 现在修复了