IN
には2つのバリエーションがあります 式:
-
expression IN (subquery)
-
expression IN (value [, ...])
同様に、ANY
を持つ2つのバリアント 構成:
-
expression operator ANY (subquery)
-
expression operator ANY (array expression)
サブクエリはどちらの手法でも機能しますが、秒 それぞれの形式、IN
値のリストが必要です (標準SQLで定義されているように)while = ANY
配列が必要です 。
どちらを使用しますか?
ANY
は後で、より用途の広い加算であり、ブール値を返す任意の二項演算子と組み合わせることができます。 IN
ANY
の特殊なケースにバーンダウンします 。実際、その2番目の形式は内部で書き直されています:
IN
= ANY
で書き直されます
NOT IN
<> ALL
で書き直されます
EXPLAIN
を確認してください 自分で確認するためのクエリの出力。これは2つのことを証明しています:
-
IN
= ANY
より速くなることはありません 。 -
= ANY
大幅に速くなることはありません。
選択は、提供しやすいものによって決定する必要があります :値のリストまたは配列(おそらく配列リテラルとして-単一の値)。
渡すIDがDB内から来る場合 とにかく、それらを直接選択する(サブクエリ)か、JOIN
を使用してソーステーブルをクエリに統合する方がはるかに効率的です。 (@muのコメントのように)
長いリストを渡すには クライアントからの価値観を活用して、最高のパフォーマンスを得る 、配列を使用します、unnest()
結合するか、VALUES
を使用してテーブル式として提供します (@PinnyMがコメントしたように)。ただし、JOIN
可能な重複を保持します 提供された配列内/IN
中に設定 または= ANY
しない。詳細:
- 大きなINを使用してPostgresクエリを最適化する
NULL値が存在する場合、NOT IN
多くの場合、間違った選択であり、NOT EXISTS
正しいでしょう(そしてより速くも):
- 他のテーブルに存在しない行を選択します
= ANY
の構文
配列式の場合、Postgresは以下を受け入れます:
- 配列コンストラクター (配列はPostgres側の値のリストから構築されます)形式:
ARRAY[1,2,3]
- または配列リテラル
'{1,2,3}'
の形式の 。
無効な型キャストを回避するために、明示的にキャストできます:
ARRAY[1,2,3]::numeric[]
'{1,2,3}'::bigint[]
関連:
- PostgreSQL:配列をプロシージャに渡す際の問題
- カスタム型配列をPostgres関数に渡す方法
または、できた VARIADIC
を使用してPostgres関数を作成します パラメータ。個々の引数を取り、それらから配列を形成します。
- 単一のパラメータで複数の値を渡す
Rubyから配列を渡す方法は?
id
を想定 integer
になる :
MyModel.where('id = ANY(ARRAY[?]::int[])', ids.map { |i| i})
しかし、私はRubyに手を出しているだけです。 @muは、この関連する回答で詳細な手順を提供します:
- ルビーのSQLクエリに値の配列を送信しますか?