4

私はフィールドを持っています:ages pg_catalog.int4range[][][]
値の例は、 {"[0,6)","[8,10)"}0-6 と 8-10 の 2 つの範囲を意味します。
チェックするWHERE句に正しい条件を追加する方法:

  • 9 と 3 の適合例の値
  • 9 と 9 は適合しません (範囲ごとに 1 つの値のみが適合する必要があります)

のようなものWHERE ages <@ ARRAY[9,3]WHERE ages <@ ARRAY[9,9]

更新
ロジックは、子供の年齢ルールを適用するための契約条件を記述します。すべてのデータを 1 つのフィールド内に保持し、値と範囲を交差させるためだけに、チェックと比較のいくつかの段階を回避することは魅力的だと考えていました。
通常、範囲の数は可変で、1、2、3、4 などになります。チェックの値はカウントされ、一致する数の範囲にのみ適用されます。

4

1 に答える 1

3

問題を明確にする

質問すると、1 次元配列が表示されます。したがって、適切な列定義を使用してください。

ages int4range[]

混乱する以外に違いがあるわけではありません。マニュアルから配列型の宣言の章を引用します。

現在の実装では、宣言された次元数も強制されません。特定の要素型の配列は、サイズや次元数に関係なく、すべて同じ型であると見なされます。したがって、配列のサイズまたは次元数を宣言すること CREATE TABLEは、単なるドキュメントです。実行時の動作には影響しません。

また、質問自体があいまいです。元。:

INSERT INTO tbl(ages) VALUES ('{"[0,6)","[5,9)","[8,10)"}')

テスト: '{5,8,7}'::int[].

順番に適用すると、チェックは失敗します:
5最初の範囲に適合します[0,6)
82 番目の範囲に適合します[5,9)
73 番目の範囲には適合しません[8,10)

ただし、異なる順序で適用する5,7,8と、チェックは成功します。必要がある

  1. 重複しない間隔を保証します。
  2. または、定義された順序でチェックを適用します。
  3. いずれかの側の要素の数が常に一致することを明確にします。

最後に、何をしようとしているのかについての説明を質問に編集します。コメントで重要な情報を隠さないでください。

答え

コメントによると、上記のカタログから 1.、2.、および 3. を想定しています。このクエリは、指定された( )に適合するかどうかから、すべてages( array of int4range) をテストします。tblage_listint[]

WITH tbl(id, ages) AS (
   VALUES
     (1, '{"[0,2)","[4,6)","[8,10)"}'::int4range[])
    ,(2, '{"[2,4)","[6,8)","[9,10)"}')
   )                                    -- stand-in for table
SELECT id, bool_and(i <@ r) AS passes_test
FROM  (
   SELECT id
         ,unnest('{1,5,9}'::int[]) AS i -- supply age_list here
         ,unnest(ages)             AS r
   FROM tbl
   ) AS sub
GROUP  BY 1

戻り値:

 id | passes_test
----+------------
  1 | t
  2 | f

主なポイント

  • CTEtblは、テーブルの単なる代用です。tbl実際に存在する場合は削除できます。

  • 2 つのunnest()関数は、2 つの配列を並べてネスト解除します。id行を識別するために (任意の一意の列)を追加します。

  • 要素ごとに<@演算子で範囲に含まれているか確認し、で再集計しbool_andます。TRUEすべてのチェックが の場合にのみ を返しますTRUE

于 2013-02-02T23:18:15.047 に答える