PostgreSQLのIN演算子とANY演算子


回答:


157

(どちらINANY「演算子」ではありません。「構成」または「構文要素」です。)

論理的に、マニュアルを引用して

INと同等= ANYです。

しかし、2つのがある構文バリアントINとの二つの変種がANY。詳細:

IN 取ってセットすることと等価である= ANY取っセットをここに示されたように、:

しかし、それぞれの2番目のバリアントは他のものと同等ではありません。ANYコンストラクトの2番目のバリアントは配列(実際の配列型でなければなりません)をIN取りますが、2番目のバリアントは値のコンマ区切りリストを取ります。これにより、値を渡す際にさまざまな制限が発生し、特殊なケースではさまざまなクエリプランが発生する可能性があります。

ANY より用途が広い

ANYそれだけでなく、さまざまな演算子と組み合わせることができるよう構築体は、はるかに汎用性があります=。例:

SELECT 'foo' LIKE ANY('{FOO,bar,%oo%}');

多数の値の場合、セットを提供することで、それぞれのスケールが向上します。

関連:

反転/反対/除外

" id指定された配列内のを検索する":

SELECT * FROM tbl WHERE id = ANY (ARRAY[1, 2]);

反転:「列の検索idない配列にします」:

SELECT * FROM tbl WHERE id <> ALL (ARRAY[1, 2]);
SELECT * FROM tbl WHERE id <> ALL ('{1, 2}');  -- equivalent array literal
SELECT * FROM tbl WHERE NOT (id = ANY ('{1, 2}'));

3つすべて同等。1つ目は配列コンストラクター、もう2つは配列リテラルです。データ型は、コンテキストから明確に導出できます。それ以外の場合、などの明示的なキャストが必要になる場合があり'{1,2}'::int[]ます。

を含む行はid IS NULL、これらの式のいずれも渡しません。NULLさらに値を含めるには:

SELECT * FROM tbl WHERE (id = ANY ('{1, 2}')) IS NOT TRUE;

4
2番目のバリアントの結果は常に同じであることを明示的に明確にするとよいでしょう。私はそれが事実であることを99%確信していますが、答えはそれを述べていないようです。つまり、クエリプランが異なる可能性がある場合でもSELECT * from mytable where id in (1, 2, 3)、常にと同じ行になりSELECT * from mytable where id = ANY('{1, 2, 3}')ます。
KPD

1
ANY !=演算子と組み合わせることはできません。私は、それが文書化されていると思いませんが、ないselect * from foo where id != ANY (ARRAY[1, 2])と同じではありませんselect * from foo where id NOT IN (1, 2)。一方、select * from foo where NOT (id = ANY (ARRAY[1, 2]))期待どおりに動作します。
qris

1
@qris:演算子ANYと組み合わせることができます!=。しかし、それだけではありません。上記の章を追加しました。(これ<>は標準SQLの演算子です!=
-Postgres

NULL値を含む最後のバージョンはどのように機能しますか?思いWHERE id = ANY (ARRAY[1, 2]) OR id IS NULL;だけでも同様に動作しますか?
dvtan

1
@dvtan:実際に一致する場合にのみ評価される(id = ...) IS NOT TRUEため、機能します。結果またはテストに合格します。参照:stackoverflow.com/a/23767625/939860。追加した式は何か他のものをテストします。これは同等ですid = ...TRUEFALSENULLWHERE id <> ALL (ARRAY[1, 2]) OR id IS NULL;
Erwin Brandstetter

3

2つの明白なポイントと、他の回答のポイントがあります。

  • サブクエリを使用する場合、これらはまったく同じです。

    SELECT * FROM table
    WHERE column IN(subquery);
    
    SELECT * FROM table
    WHERE column = ANY(subquery);

一方:

  • INオペレーターのみが単純なリストを許可します。

    SELECT * FROM table
    WHERE column IN(… ,  , …);

それらがまったく同じであると仮定するANYと、リストで機能しないことを忘れたときに何度か私を見つけました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.