我有一个包含appointment
条记录的表格,用户会选择日期范围(begin_date
,end_date
)。我希望获得落在此日期范围内的appointment
,以及过去和未来中最接近此日期范围的实例(也就是前一次出现和下一次出现)。
我认为解决这个问题的最佳方法是使用CTE和自联接,但我对另一种策略持开放态度。这是我目前的查询:
WITH present AS
(SELECT appt.ewssubject, appt.ewsstart::DATE, appt.ewsend::DATE
FROM appointment appt
WHERE (appt.ewsstart, appt.ewsend) OVERLAPS (begin_date::DATE, end_date::DATE))
SELECT
present.ewssubject, present.ewsstart, present.ewsend,
past.ewssubject AS pastsubject, past.ewsstart::DATE AS paststart,past.ewsend::DATE AS pastend,
future.ewssubject AS futuresubject, future.ewsstart::date AS futurestart, future.ewsend::date AS futureend
FROM present
LEFT JOIN appointment AS past USING (ewssubject)
LEFT JOIN appointment AS future USING (ewssubject)
WHERE
present.ewssubject = past.ewssubject AND
present.ewssubject = future.ewssubject AND
past.ewsend < present.ewsstart AND
future.ewsstart > present.ewsend
ORDER BY present.ewsstart ASC
我得到了appointments
的大量列表,并且有很多重复 - 就像这样:
subject start end last_start last_end next_start next_end
DINNER 2015-09-18 2015-09 18 2015-09-17 2015-09-17 2015-09-19 2015-09-19
DINNER 2015-09-18 2015-09 18 2015-09-17 2015-09-17 2015-09-19 2015-09-19
... // more repeats! :(
我想要做的就是减少重复次数,例如这种格式:
subject start end last_start last_end next_start next_end
DINNER 2015-09-18 2015-09-18 2015-09-17 2015-09-17 2015-09-19 2015-09-19
DINNER 2015-09-21 2015-09-21 2015-09-18 2015-09-18 2015-10-02 2015-10-02
... // and so on
n.b。 appointment
可以跨越多天。
如何修复查询?或者还有另外一个我可以写的吗?
答案 0 :(得分:1)
您没有输入有关数据的详细信息,因此我不确定这是否是个好主意,但您可以使用window functions:
select
ewssubject, ewsstart, ewsend,
lag(ewsstart) over (partition by ewssubject order by ewstart) prior_start,
lag(ewsend) over (partition by ewssubject order by ewstart) prior_end,
lead(ewsstart) over (partition by ewssubject order by ewstart) next_start,
lead(ewsend) over (partition by ewssubject order by ewstart) next_end
from appointment
order by ewstart;