私は興味深い問題を解決しようとしています。他のデータの中でも、これらの列を含むテーブルがあります (このサンプルの日付はヨーロッパ形式で表示されています - dd/mm/yyyy):
n_place_id dt_visit_date
(integer) (date)
========== =============
1 10/02/2012
3 11/03/2012
4 11/05/2012
13 14/06/2012
3 04/10/2012
3 03/11/2012
5 05/09/2012
13 18/08/2012
基本的に、各場所は複数回訪問することができ、日付は過去 (完了した訪問) または将来 (計画された訪問) の場合があります。簡単にするために、今日の訪問は計画された将来の訪問の一部です。
ここで、このテーブルで選択を実行する必要があります。これにより、このテーブルから一意の場所 ID (日付なし) が取得され、次の順序で並べ替えられます。
- 今後の訪問は過去の訪問の前に行われます
- 今後の訪問は、同じ場所への過去の訪問よりも優先されます
- 今後の訪問については、同じ場所のソートで最も古い日付を優先する必要があります
- 過去の訪問の場合、同じ場所のソートでは最新の日付が優先される必要があります。
たとえば、上記のサンプル データの場合、必要な結果は次のとおりです。
5 (earliest future visit)
3 (next future visit into the future)
13 (latest past visit)
4 (previous past visit)
1 (earlier visit in the past)
これで、次のように句を使用case when
して目的の並べ替えを実現できます。order by
select
n_place_id
from
place_visit
order by
(case when dt_visit_date >= now()::date then 1 else 2 end),
(case when dt_visit_date >= now():: date then 1 else -1 end) * extract(epoch from dt_visit_date)
これは私が必要とすることを行いますが、重複する ID が含まれていますが、一意の場所 ID が必要です。select ステートメントに追加しようとするdistinct
と、postgres はorder by
、select 句に が必要であると不平を言いますが、そこに日付があるため、unique はもはや意味がありません。
どういうわけか、1 つの select ステートメントで必要な結果を取得する方法があるはずだと感じていますが、その方法について頭を悩ませることはできません。
これができない場合は、もちろん、コード内ですべてを実行する必要がありますが、これを 1 つの SQL ステートメントで行うことをお勧めします。
PS ソートするデータセットは大きくないため、パフォーマンスについては心配していません。句が適用されると、where
約 10 を超えるレコードが含まれることはほとんどありません。