0

假设我有以下数据:

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

我想要的是查询这个表,以便我得到MIN(time)per 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 的更改。

4

1 回答 1

1

这不是漂亮的代码,但是。使用 django 的“额外”查询集方法和 where 作为参数,您可以实现取回所需的结果集。IE

Table.objects.extra(where=['id IN (SELECT id FROM table_name' 
                           '       GROUP BY user_id HAVING MIN(time))'])
于 2013-01-22T16:59:28.960 回答