Django 1.4 / 1.5控制GROUP BY结合HAVING

时间:2013-01-22 15:53:04

标签: django django-orm

说我有以下数据:

| id | user_id | time |
| 1  | 1       | 10.0 |
| 2  | 1       | 12.0 |
| 3  | 2       | 11.0 |
| 4  | 2       | 13.0 |

我想要查询此表格,以便每MIN(time)获得user_id

| id | user_id | time |
| 1  | 1       | 10.0 |
| 3  | 2       | 11.0 |

所以我的SQL想要这样:

SELECT id, user_id, time FROM table GROUP BY user_id HAVING MIN(time)

但是,当尝试使用.annotate(Min('time'))时,Django会在任意(错误)字段上GROUP BY。例如,请参阅以下代码和生成的(简化的)SQL:

>>> Table.objects.annotate(Min('time')).query
SELECT id, user_id, time, MIN(time) FROM table GROUP BY id, user_id, time

>>> Table.objects.values('id', 'time').annotate(Min('time')).query
SELECT id, time, MIN(time) FROM table GROUP BY id, time

生成的SQL远非我想要的输出。我目前正在通过使用原始SQL来解决这个问题,但是这首先违背了使用ORM的目的。此外,由于无法应用正常的.filter(),因此难以重复使用生成的代码。

关于这种类型的查询存在类似的问题,但它们相当陈旧,并且自1.3以来不会对Django进行更改。

1 个答案:

答案 0 :(得分:1)

这不是漂亮的代码而是。使用django的'额外'查询集方法以及作为参数的位置,您可以实现获取所需的结果集。即。

Table.objects.extra(where=['id IN (SELECT id FROM table_name' 
                           '       GROUP BY user_id HAVING MIN(time))'])