SELECT generate_series(date_trunc('week', date '2013-02-01' + interval '6 days')
, date_trunc('week', date '2013-02-01' + interval '1 month - 1 day')
, interval '1 week')::date AS day
UNION SELECT date '2013-02-01'
ORDER BY 1;
このバリアントは副選択を必要としないGREATEST
かGROUP BY
、必要な行のみを生成します。より簡単に、より速く。UNION
1列の方が安いです。
その月の最初の月曜日を計算するには、前月の最初の日に 6 日を追加します。date_trunc('week', ...)
月の最終月曜日date_trunc('week', ...)
を取得するには、1 か月を加算して 1 日前を減算します。これは便利に 1 つの式
に詰め込むことができます。
interval
'1 month - 1 day'
UNION
(ではありません UNION ALL
) 月曜日として既に含まれていない限り、追加する月の最初の日。
date
+のinterval
結果はであることに注意してtimestamp
ください。ここではこれが最適です。詳細な説明:
オートメーション
CTE で日付系列の開始を指定できます。
WITH t(d) AS (SELECT date '2013-02-01') -- enter 1st of month once
SELECT generate_series(date_trunc('week', d + interval '6 days')
, date_trunc('week', d + interval '1 month - 1 day')
, interval '1 week')::date AS day
FROM t
UNION SELECT d FROM t
ORDER BY 1;
または、繰り返し呼び出しを行う際に便利なように、単純な SQL 関数にラップします。
CREATE OR REPLACE FUNCTION f_week_starts_this_month(date)
RETURNS SETOF date AS
$func$
SELECT generate_series(date_trunc('week', $1 + interval '6 days')
, date_trunc('week', $1 + interval '1 month - 1 day')
, interval '1 week')::date AS day
UNION
SELECT $1
ORDER BY 1
$func$ LANGUAGE sql IMMUTABLE;
電話:
SELECT * FROM f_week_starts_this_month('2013-02-01');
月の最初の日の日付を渡しますが、どの日付でも機能します。翌月の初日とすべての月曜日。