2014-04-13 212 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'包含/獨佔邊框時應遵守。 –

相關問題