使用Django 1.65 Python 3.4.1 Oracle db
db'Locations'中的表:
location | update_time | num_01 | num_02 | num_03 |
-----------+-----------------+-----------+--------+--------
B | 06 Feb 18 04:14 | 42 | 43 | 55
C | 22 Feb 17 04:14 | 77 | 99 | 23
A | 05 Feb 18 04:14 | 48 | 43 | 21
A | 01 Feb 18 04:14 | 82 | 83 | 74
我想为每个位置选择包含最新update_time的行。
上表的结果应为:
location | update_time | num_01 | num_02 | num_03 |
-----------+-----------------+-----------+--------+--------
A | 05 Feb 18 04:14 | 48 | 43 | 21
B | 06 Feb 18 04:14 | 42 | 43 | 55
C | 22 Feb 17 04:14 | 77 | 99 | 23
我可以使用查询集返回每个位置的最新更新时间:
latest_updates = Locations.objects.values('location').annotate(max_date=Max('update_time')).order_by('location')
但这只会在我查找整行时返回location和max update_time - num_01,num_02,num_03。
我花了很多时间搜索stackoverflow,但没有什么比这更合适了。 Oracle似乎不支持我可以开始工作的排序和不同选项。
由于某些原因我无法导入Subquery所以这对我来说不是一个选项,而且我仍然坚持使用这个版本的django等,因为它正在起作用。
该表最终会有合理数量的数据,所以我正在寻找一个合理有效的解决方案。
答案 0 :(得分:1)
对于Django 1.11+,您也可以Subquery,所以这样的方法应该起作用:
from django.db.models import Subquery, OuterRef, F
qs = Location.objects.all()
# make a subquery (filter, order, get 'id')
sq = qs.filter(location=OuterRef('location')).order_by('-update_time').values('id')
# use subquery in your query (via annotation + filter)
qs.annotate(latest=Subquery(sq[:1])).filter(id=F('latest'))
答案 1 :(得分:0)
你应该使用,
latest_updates = Locations.objects.order_by('location', '-update_time').distinct('location')
答案 2 :(得分:0)
您可以尝试以下方法:
Locations.objects.order_by('location', '-update_time').distinct('location')
就我而言,它适用于Django 2.1
答案 3 :(得分:-1)
我在这里找到的最佳解决方案:https://gist.github.com/ryanpitts/1304725
'''
given a Model with:
category = models.CharField(max_length=32, choices=CATEGORY_CHOICES)
pubdate = models.DateTimeField(default=datetime.now)
<other fields>
Fetch the item from each category with the latest pubdate.
'''
model_max_set = Model.objects.values('category').annotate(max_pubdate=Max('pubdate')).order_by()
q_statement = Q()
for pair in model_max_set:
q_statement |= (Q(category__exact=pair['category']) & Q(pubdate=pair['max_pubdate']))
model_set = Model.objects.filter(q_statement)