web-dev-qa-db-ja.com

期間内の一連の月を生成する

特定の期間内に一連の月を生成したい。

私が試してみました:

select  GENERATE_SERIES( '06/25/2016'::DATE, '12/15/2016'::DATE, '1 month' )

それは返します:

"generate_series"
"2016-06-25 00:00:00-06"
"2016-07-25 00:00:00-06"
"2016-08-25 00:00:00-06"
"2016-09-25 00:00:00-06"
"2016-10-25 00:00:00-06"
"2016-11-25 00:00:00-07"

終了日に問題があります。次のような結果が必要です。

"generate_series"
 "2016-06-25 00:00:00-06"
 "2016-07-25 00:00:00-06"
 "2016-08-25 00:00:00-06"
 "2016-09-25 00:00:00-06"
 "2016-10-25 00:00:00-06"
 "2016-11-25 00:00:00-07"
 "2016-12-15 00:00:00-07"

PostgreSQLを使用しています。

4
Vijay Tambade

Evanが、なぜgenerate_series()だけでは望みどおりに処理できないのかを説明します。しかし、それは単純なUNIONで行うことができます:

_select generate_series('2016-06-25'::timestamp, '2016-12-15', '1 month') 
         as g_date 
union 
select '2016-12-15'
-- order by g_date 
;
_

または_UNION ALL_:

_select generate_series('2016-06-25'::timestamp, 
                       '2016-12-15' - interval '1 day', 
                       '1 month') as g_date 
union all
select '2016-12-15' ;
_

また、generate_series()出力は_timestamp without timezone_タイプであることに注意してください。 dateタイプが必要な場合は、キャストする必要があります。

_select generate_series('2016-06-25'::timestamp, 
                       '2016-12-15' - interval '1 day', 
                       '1 month')::date as g_date 
union all
select '2016-12-15'::date ;
_
4
ypercubeᵀᴹ

呼び出している関数にはgenerate_series(start, stop, step interval)のシグネチャがあります。このため、stop引数の後にデータポイントを生成することはできません。止まる。正気のために、あなたは月の25日が欲しいので、あなたが必要なのは

  1. stop月末など、25日以降にハードコーディングされます。

    SELECT ts
    FROM generate_series(
      '06/25/2016'::DATE,
      '12/31/2016'::DATE,
      '1 month'
    ) AS t(ts);
    
  2. startstopを最初の月とし、24日を追加して25日目を取得します。

    SELECT ts + '24 days'
    FROM generate_series(
      '06/1/2016'::DATE,
      '12/1/2016'::DATE,
      '1 month'
    ) AS t(ts);
    
  3. この方法のように、25日目以降のストップポイントを計算するには...月の最終日を計算します。

    SELECT ts
    FROM generate_series(
      '06/25/2016'::DATE,
      (date_trunc('month', '12/15/2016'::date) + '1 month - 1 day')::DATE,
      '1 month'
    ) AS t(ts);
    
3
Evan Carroll