我的events表有startdate和enddate列。它还有一个循环布尔列,用于将事件标记为循环。我只需要支持每周的递归。如何为这些重复发生的事件选择下一个合适的日期?
给定以下示例数据和编写本文的时间,我如何才能获得以下结果?
startdate enddate nextdate
12/29/14 12/31/15 1/12/15
1/2/15 4/1/15 1/9/15
6/1/14 12/31/14 null
4/1/15 12/31/15 4/1/15
更新:我刚写了这个函数,但现在我想知道有没有更有效的方法……
CREATE OR REPLACE FUNCTION nextdowinrange(startdate timestamp with time zone, enddate timestamp with time zone)
RETURNS timestamp with time zone AS
$BODY$
DECLARE
loopday int;
nextdate timestamp with time zone;
BEGIN
--RANGE PAST
IF enddate < current_timestamp THEN
RETURN null;
--RANGE NOT STARTED
ELSIF startdate > current_timestamp THEN
RETURN startdate;
--SAME DAY OF WEEK
ELSIF extract(dow from startdate) = extract(dow from current_timestamp) THEN
RETURN startdate;
--FIND NEXT
ELSE
loopday:= 0;
LOOP
IF extract(dow from now() + (loopday || ' days')::interval) = extract(dow from startdate) THEN
nextdate:= now() + (loopday || ' days')::interval;
END IF;
EXIT WHEN extract(dow from now() + (loopday || ' days')::interval) = extract(dow from startdate);
loopday:= loopday + 1;
END LOOP;
RETURN nextdate;
END IF;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
发布于 2015-01-08 17:48:47
下面的查询将为您提供所需的内容。希望这能给你一个基本的想法,你可以根据你的需要进行修改。
我随意添加了一个id列(使连接更容易),并假定startdate和enddate的类型为date
alter table mydates add date_id serial primary key
让我解释一下查询:内部查询生成一系列日期。下一个查询获取该序列中最早的未来日期(对于每个id) -这将不会返回enddate为过去的行的记录。因此,有一个外部查询将那些丢失的记录添加到nextdate为空的位置。
SELECT a.startdate,a.enddate,nextdate FROM -- outer query with left join to get finished ranges
mydates a
LEFT JOIN
-- select the earliest date in the future from the series
-- This will not contain rows where the enddate is in the past
(SELECT date_id,min(theweeks)::date AS nextdate FROM
(SELECT date_id, generate_series -- Get a series of the week dates
(
startdate
,enddate
, '1 week'::interval) as theweeks
FROM mydates
) AS daterange
WHERE now() < theweeks
GROUP BY date_id) AS nextdates
ON nextdates.date_id = a.date_id
ORDER BY a.date_id
https://stackoverflow.com/questions/27834235
复制相似问题