2

毎年繰り返されるイベントを表すアイテムのセットを含むデータベース テーブルがあります。レコード セットは、月と日ごとに保存されます。カレンダーの日付の範囲に対応するイベント レコードを取得する必要があることがよくあります。私は Django ORM を使用してレコードを操作しているので、現時点では日付を対応するQオブジェクトに変換します (たとえばQ(month=month, day=day)MyModel.objects.filter().

私の日付範囲が新年と交差する場合、問題が発生します。2013 年 12 月 31 日から 2014 年 1 月 1 日までのイベントが必要な場合は、次のようにします。

MyModel.objects.filter(Q(month=12, day=31) | Q(month=1, day=1))

しかし、私は結果を次の順序で取得します。

month = 1, day = 1
month = 12, day = 31

代わりに、次の順序で結果を取得したいと思います。

month = 12, day = 31
month = 1, day = 1

質問を不必要に複雑にする理由から、単純にクエリを 2 つのクエリ (各年に 1 つずつ) に分割することはできません。1 つのクエリを作成して、目的の順序で結果を取得したいと考えています。必要に応じて、クエリを再構成できます。

便利なのはわかっていextraますが、使い方がよくわかりません。

アップデート:

意図したソリューションに少し近づくために、絶対的な順序付けを課すために、ユリウス日を「計算された」フィールドとして結果に滑り込ませ、そのフィールドで並べ替えることができました。しかし、それを行う方法は?

4

1 に答える 1

2

extraSQLCASEステートメントを使用してトリッキーなソリューションがあります:

start_month = 12
start_day = 31
end_month = 1
end_day = 1
query = (models.MyModel.objects.filter(Q(month=start_month, day=start_day) | 
                                       Q(month=end_month, day=end_day))
                       .extra(select={'order_me': '''CASE WHEN month*31+day < %s*31+%s 
                                                          THEN (12+month)*31+day 
                                                          ELSE (month)*31+day
                                                   END''' % (start_month, start_day)})
                       .extra(order_by=['order_me']))

このフィールドを追加するとすぐに(これは良くありません) 、日付範囲order_meではなく述語で使用する必要があると思いますQ(...)|Q(...)

query = (models.MyModel.objects.all()
                   .extra(select={'order_me': """CASE WHEN month*31+day < %s*31+%s 
                                                    THEN (12+month)*31+day 
                                                    ELSE (month)*31+day
                                               END""" % (start_month, start_day) })
                   .extra(order_by=['order_me'])
                   .extra(where=['order_me < (12 + %s) * 31 + %s' % (end_month,
                                                                     end_day)]))
于 2013-10-28T16:08:05.377 に答える