web-dev-qa-db-ja.com

日付範囲の配列の要素?

日付の配列があり、配列内の要素のいずれかが特定の日付範囲内にあるかどうかを確認したい。

例(疑似コード-機能せず、読みやすくするためにラップされています):

SELECT ARRAY['2017-01-01'::DATE, '2017-02-03'::DATE] && 
    daterange('2017-01-01', '2017-01-31', '[]');

この例で表示しようとしているのは(動作しないものの)、日付の配列と日付範囲の値の間に重複があるかどうかです。

理想的には、セットでそれを行うことができ、2つの間に和集合がある場合は解決できますが、daterangeオブジェクトを何かにキャストすることは不可能のようです。

私はなんとかこれを機能させることができましたが、その後行を減らす方法を見つけることができません:

SELECT daterange('2017-01-01', '2017-01-31', '[]') @> 
    unnest(ARRAY ['2017-01-01' :: DATE, '2016-07-30' :: DATE]);

これは私に複数の行を返します:

?column?
----------
 t
 f
(2 rows)

誰かがこれに対する指針を持っていますか?どんな助けでもありがたいです。

5
aodj

日付の配列があり、配列内の要素のいずれかが特定の日付範囲内にあるかどうかを確認したい

クエリに応じて、使用できます

  • 彼の答えのjoanolo によって言及されたbool_orを使用した行の集約。
  • または、 ANY を含む演算子@>を使用できます

    SELECT daterange('2017-01-01', '2017-01-31', '[]')  @> 
      ANY(ARRAY['2017-01-01'::date, '2017-02-03'::date]);
    
    SELECT daterange('2017-01-01', '2017-01-31', '[]')  @> 
      ANY(ARRAY['2016-01-02'::date, '2016-01-09'::date]);
    
5
Evan Carroll

集計関数bool_or あなたが探しているものを達成するために:

SELECT
    bool_or(date_range @> a_date) AS some_of_the_dates_lies_within_range
FROM
    (
    SELECT
        unnest(ARRAY['2017-01-01'::DATE, '2017-02-03'::DATE]) AS a_date, 
        daterange('2017-01-01', '2017-01-31', '[]') AS date_range
    ) AS s0
2
joanolo

日付の配列がテーブル列であり、それにインデックスを付けたい場合は、その場で範囲から配列を生成し、配列と範囲からの配列の重複を見つけることを検討できます。このように、配列の列にGINインデックスがある場合、クエリプランナーで使用されます。

SELECT ARRAY['2019-01-01'::date, '2019-02-03'::date] && (
    SELECT ARRAY(SELECT d::date
    FROM GENERATE_SERIES(date '2019-01-01', date '2019-01-31', '1 day') AS d)
)
0
twinmind