我正在尝试解决一个有趣的问题。我有一个表格,其中包含这些列(此示例中的日期以欧洲格式显示 - 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。如果我尝试添加distinct
到 select 语句中,postgres 会抱怨我必须order by
在 select 子句中添加 - 但是唯一的将不再有意义,因为我在那里有日期。
不知何故,我觉得应该有一种方法可以在一个 select 语句中获得我需要的结果,但我不知道该怎么做。
如果这不能完成,那么,当然,我将不得不在代码中完成整个事情,但我更愿意在一个 SQL 语句中完成它。
PS我不担心性能,因为我要排序的数据集并不大。应用该where
子句后,它很少会包含超过 10 条记录。