1

日付範囲を受け入れ、月曜日である日付範囲内の日付を返す PostgreSQL の関数が必要です。誰でもこれを行う方法を知っていますか?

4

2 に答える 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

SQL フィドル。

于 2014-04-13T23:59:04.097 に答える