我的问题类似于这个问题: How to select only the latest rows for each user? 但我正在用Django实现这一点。
在下面的例子中(我从上面的问题中借用),我只需要为每个用户提取最后一行。另外,就我而言,我只想获取特定user_ids列表的行。
id | user_id | period_id | completed_on
----------------------------------------
1 | 1 | 1 | 2010-01-01
2 | 2 | 1 | 2010-01-10
3 | 3 | 1 | 2010-01-13
4 | 1 | 2 | 2011-01-01
5 | 2 | 2 | 2011-01-03
6 | 2 | 3 | 2012-01-13
... | ... | ... | ...
如果user_list为[1,2],我想得到这样的结果:
id | user_id | period_id | completed_on
----------------------------------------
4 | 1 | 2 | 2011-01-01
6 | 2 | 3 | 2012-01-13
我是用过滤器编写的,但无法找到正确的方法。
PeriodTable.objects.filter(user__in=user_list, period_id=max(....?)).values(...)
答案 0 :(得分:0)
首先是一个小帮助函数,用于将一个int数组转换为一个sql IN
子句的参数。
def to_sql_in(arr):
return ','.join(map(str, arr))
然后您可以使用cursor直接查询您的数据库,因为在这种情况下我认为过滤器不够。
user_list = [1, 2]
with connection.cursor() as cursor:
cursor.execute('''SELECT t.Id, t.User_Id, t.Period_Id, t.Completed_On
FROM Table1 t
JOIN (SELECT Max(completed_on) Max_Completed_On, t.User_Id
FROM Table1 t
GROUP BY t.User_Id) t2
ON t.User_Id = t2.User_Id AND t.Completed_On = t2.Max_Completed_On
WHERE t.User_Id IN ({0})'''.format(to_sql_in(user_list)))
r = cursor.fetchall()
columns = [col[0] for col in cursor.description]
print [dict(zip(columns, row)) for row in r]
答案 1 :(得分:0)
如果通过“last”指的是每个用户的最大completed_on
,并且此列未排序,则可能您必须直接使用SQL(如已建议的那样)。但是,如果“last”表示每个用户的表的最后一个条目,则可以直接使用Django聚合API解决问题。假设您的模型是M
:
from django.db.models import Max
q = M.objects.filter(user_id__in=users_list)
max_ids = q.values('user_id').annotate(Max('id')).values_list('id__max')
result = M.objects.filter(id__in=max_ids)
第三行只按user_id
分组,但记住每个组的最大id
行,并创建这些ID的列表。最后,结果是带有这些ID的行集。
我强调,如果您想为每个用户获取数据库中的最后一个条目,此解决方案只能 。