2014-04-13 198 views

回答

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)的范围内进行调整以适用于包含式和专有范围with range functions.

  • 表达式(8 - EXTRACT(ISODOW FROM a)::int) % 7返回到下一个星期一的天数。如果已经是星期一,则为0The manual about 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 

SQL Fiddle.

2
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 
+0

尼斯和简单。一个小小的抱怨:当使用'daterange'包含/独占边框时应遵守。 –

相关问题