【发布时间】:2013-07-27 03:34:14
【问题描述】:
假设我们有 Django ORM 模型Meetup,其定义如下:
class Meetup(models.Model):
language = models.CharField()
speaker = models.CharField()
date = models.DateField(auto_now=True)
我想使用单个查询来获取 每种语言的最新活动。
>>> Meetup.objects.create(language='python', speaker='mike')
<Meetup: Meetup object>
>>> Meetup.objects.create(language='python', speaker='ryan')
<Meetup: Meetup object>
>>> Meetup.objects.create(language='node', speaker='noah')
<Meetup: Meetup object>
>>> Meetup.objects.create(language='node', speaker='shawn')
<Meetup: Meetup object>
>>> Meetup.objects.values("language").annotate(latest_date=models.Max("date")).values("language", "speaker", "latest_date")
[
{'speaker': u'mike', 'language': u'python', 'latest_date': ...},
{'speaker': u'ryan', 'language': u'python', 'latest_date': ...},
{'speaker': u'noah', 'language': u'node', 'latest_date': ...},
{'speaker': u'shawn', 'language': u'node', 'latest_date': ...},
]
天啊!我们收到了最新的活动,但分组有误!
似乎我需要一种方法来 GROUP BY 和 language 但 SELECT 在不同的
一组字段?
更新 - 这种查询似乎很容易用 SQL 表达:
SELECT language, speaker, MAX(date)
FROM app_meetup
GROUP BY language;
我想要一种不使用 Django 的 raw() 的方法来做到这一点 - 有可能吗?
更新 2 - 经过大量搜索,似乎在 SO 上有类似的问题:
- Django Query that gets the most recent objects
- How can I do a greatest n per group query in Django
- MySQL calls this sort of query a group-wise maximum of a certain column。
更新 3 - 最后,在 @danihp 的帮助下,您能做的似乎是最好的 是两个查询。我使用了以下方法:
# Abuse the fact that the latest Meetup always has a higher PK to build
# a ValuesList of the latest Meetups grouped by "language".
latest_meetup_pks = (Meetup.objects.values("language")
.annotate(latest_pk=Max("pk"))
.values_list("latest_pk", flat=True))
# Use a second query to grab those latest Meetups!
Meetup.objects.filter(pk__in=latest_meetup_pks)
这个问题是我上一个问题的后续:
【问题讨论】:
-
很遗憾,这是 MySQL。在postgres中可以直接使用DISTINCT ON获取最新的group shameless plug for my answer on another question。
标签: mysql django django-models ranking django-orm