69

PostgreSQL データベースの 2 つの日付 (それらを含む) の間の日のリストを取得したいと思います。たとえば、私が持っていた場合:

  • 開始日: 2012 年 6 月 29 日
  • 終了日: 2012 年 7 月 3 日

結果は次のようになります。

29 june 2012
30 june 2012 
1 july 2012 
2 july 2012 
3 july 2012

PostgreSQL でこれを行う最善の方法は何でしょうか?

ありがとう。

4

8 に答える 8

116
select CURRENT_DATE + i 
from generate_series(date '2012-06-29'- CURRENT_DATE, 
     date '2012-07-03' - CURRENT_DATE ) i

またはさらに短い:

select i::date from generate_series('2012-06-29', 
  '2012-07-03', '1 day'::interval) i
于 2012-07-09T09:05:30.057 に答える
44

としてtimestamp

select generate_series('2012-06-29', '2012-07-03', '1 day'::interval);

    generate_series     
------------------------
 2012-06-29 00:00:00-03
 2012-06-30 00:00:00-03
 2012-07-01 00:00:00-03
 2012-07-02 00:00:00-03
 2012-07-03 00:00:00-03

またはキャストdate:

select (generate_series('2012-06-29', '2012-07-03', '1 day'::interval))::date;

 generate_series 
-----------------
 2012-06-29
 2012-06-30
 2012-07-01
 2012-07-02
 2012-07-03
于 2012-09-22T10:34:37.913 に答える
8

これはそれを行う必要があります:

select date '2012-06-29' + i
from generate_series(1, (select date '2012-07-3' - date '2012-06-29')) i

副選択でstart_dateを繰り返したくない場合は、もう少し複雑になります。

with min_max (start_date, end_date) as (
   values (date '2012-06-29', date '2012-07-3')
), date_range as (
  select end_date - start_date as duration
  from min_max
)
select start_date + i
from min_max
  cross join generate_series(1, (select duration from date_range)) i;

(「繰り返しなし」の問題のはるかに優れたバージョンについては、maniekの回答を参照してください)

于 2012-07-09T08:12:31.207 に答える
7
select generate_series('2012-06-29', '2012-07-03', '1 day'::interval)::date;
于 2015-02-07T13:15:35.827 に答える
5

このような場合、システムに日付テーブルがあると一般的に便利です。

数値テーブルと同じように、特に大規模なデータセットにスケールアップする場合は、その場で日付を生成するよりも非常に便利ですばやく使用できます。

1900年から2100年までのこのような日付表は非常に小さいので、保管に頭を悩ませることはあまりありません。

編集:なぜこれが投票されないのか、それはおそらくパフォーマンスに最適でしょう。さらに、他にも多くの利点があります。注文を四半期のパフォーマンス数値にリンクしたいですか?テーブル間の単純なリンク。(Order.OrderDate-> Dates.Date-> Dates.Quarter-> PerformanceTotal.Quarter)など。月の最終営業日や前月の第1火曜日などの営業日を処理する場合も同じです。数字の表のように、私はそれらを強くお勧めします!

于 2012-07-09T09:21:13.093 に答える
0

この PLpg/SQL 関数はトリックを実行します。

CREATE OR REPLACE FUNCTION getDateList(date1 date, date2 date)
RETURNS SETOF date AS
$BODY$
DECLARE
    count integer;
    lower_limit integer :=  0;
    upper_limit integer :=  date2 - date1;
BEGIN
    FOR count IN lower_limit..upper_limit LOOP
        RETURN NEXT date1 + count;
    END LOOP;
    RETURN;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
于 2012-07-09T08:22:48.337 に答える
0

日付範囲をテーブル式から取得する必要がある場合は、次の構成を使用できます。

DROP TABLE tbl ;
CREATE TABLE tbl (zdate date NOT NULL );
INSERT INTO tbl(zdate) VALUES( '2012-07-01') , ('2012-07-09' );

WITH mima AS (
        SELECT MIN(zdate)::timestamp as mi
        , MAX(zdate)::timestamp as ma
        FROM tbl
        )
SELECT generate_series( mima.mi, mima.ma, '1 day':: interval):: date
FROM mima
        ;

generate_series() は日付引数を取らないため、キャストが必要です。

于 2012-07-09T08:25:03.097 に答える
0

クエリするデータベースが既にある場合:

SELECT
   TO_CHAR(date_column,'DD Mon YYYY')
FROM
   some_table
WHERE
   date_column BETWEEN '29 Jun 2012' AND '3 JUL 2012'

GROUP BY date_column
ORDER BY date_column

これにより、次のようになります。

"29 Jun 2012"
"30 Jun 2012"
"01 Jul 2012"
"02 Jul 2012"
"03 Jul 2012"
于 2012-07-09T08:20:47.410 に答える