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 の 'extra' queryset メソッドと where を引数として使用すると、目的の結果セットを取得できます。すなわち

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