我需要 PostgreSQL 中的一个函数,它接受一个日期范围并返回星期一的日期范围内的日期。有人知道如何做到这一点吗?
问问题
1346 次
2 回答
3
create function f(dr daterange)
returns setof date as $$
select d::date
from generate_series(
lower(dr), upper(dr), interval '1 day'
) s (d)
where
extract(dow from d) = 1 and
d::date <@ dr;
;
$$ language sql;
select f(daterange('2014-01-01', '2014-01-20'));
f
------------
2014-01-06
2014-01-13
于 2014-04-13T19:21:38.300 回答
2
最有效的方法应该是找到第一个星期一并以 7 天为步长生成一个系列:
CREATE OR REPLACE FUNCTION f_mondays(dr daterange)
RETURNS TABLE (day date) AS
$func$
SELECT generate_series(a + (8 - EXTRACT(ISODOW FROM a)::int) % 7
, z
, interval '7 days')::date
FROM (
SELECT CASE WHEN lower_inc(dr) THEN lower(dr) ELSE lower(dr) + 1 END AS a
, CASE WHEN upper_inc(dr) THEN upper(dr) ELSE upper(dr) - 1 END AS z
) sub
$func$ LANGUAGE sql;
子查询提取范围的开始 (
a
) 和结束 ( ),使用范围函数z
针对包含和排除边界进行调整。该表达式
(8 - EXTRACT(ISODOW FROM a)::int) % 7
返回距离下周一的天数。0
如果已经是星期一了。手册关于EXTRACT().
generate_series()
可以迭代任何给定的间隔 - 在这种情况下为 7 天。结果是timestamp
,所以我们强制转换为date
。只生成范围内的星期一,不需要
WHERE
子句。
称呼:
SELECT day FROM f_mondays('[2014-04-14,2014-05-02)'::daterange);
回报:
day
----------
2014-04-14
2014-04-21
2014-04-28
于 2014-04-13T23:59:04.097 回答