查询集选择组的最新记录

Beh*_*e21 4 python oracle django orm django-queryset

使用 Django 1.65 Python 3.4.1 Oracle 数据库

数据库“位置”中的表:

  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   
Run Code Online (Sandbox Code Playgroud)

我想为每个位置选择具有最新 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   
Run Code Online (Sandbox Code Playgroud)

我可以使用查询集返回每个位置的最新更新时间:

latest_updates = Locations.objects.values('location').annotate(max_date=Max('update_time')).order_by('location')
Run Code Online (Sandbox Code Playgroud)

但这仅在我查找整行时返回位置和最大 update_time - num_01、num_02、num_03。

我花了很多时间搜索 stackoverflow,但没有什么合适的。Oracle 似乎不支持我可以开始工作的排序依据和不同的选项。

由于某种原因,我无法导入子查询,所以这对我来说不是一个选择,而且我坚持使用这个版本的 django 等,因为它正在工作。

该表最终将包含合理数量的数据,因此如果可能,我正在寻找合理有效的解决方案。

小智 7

你可以试试这个:

Locations.objects.order_by('location', '-update_time').distinct('location')
Run Code Online (Sandbox Code Playgroud)

就我而言,它适用于 Django 2.1


小智 5

对于 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'))
Run Code Online (Sandbox Code Playgroud)