125

Postgresのネイティブ配列タイプを使用していて、IDが配列受信者IDにないレコードを見つけようとしています。

私は彼らがどこにいるのかを見つけることができます:

SELECT COUNT(*) FROM messages WHERE (3 = ANY (recipient_ids))

しかし、これは機能しません:

SELECT COUNT(*) FROM messages WHERE (3 != ANY (recipient_ids))
SELECT COUNT(*) FROM messages WHERE (3  = NOT ANY (recipient_ids))

この状態をテストする正しい方法は何ですか?

4

7 に答える 7

164
SELECT COUNT(*) FROM "messages" WHERE NOT (3 = ANY (recipient_ids))

あなたはいつでも否定することができWHERE (condition)ますWHERE NOT (condition)

于 2012-07-30T22:44:14.540 に答える
47

少し振り返って、「3はすべてのIDと等しくない」と言うことができます。

where 3 != all (recipient_ids)

細かいマニュアルから:

9.21.4。ALL(配列)

expression operator ALL (array expression)

右辺は括弧で囲まれた式であり、配列値を生成する必要があります。左側の式は、指定された演算子を使用して評価され、配列の各要素と比較されます。これにより、ブール結果が生成される必要があります。ALLすべての比較でtrueが得られた場合(配列の要素がゼロの場合を含む)、の結果は「true」になります。誤った結果が見つかった場合、結果は「false」になります。

于 2012-07-30T22:51:32.803 に答える
29

ALL/ANY答えを増やす

all私は、結果を使用またはany達成するために、追加のメモ(たとえば、NULLについて)を評価するすべてのソリューションを好みます。別の拡張として、これらの演算子について考える方法があります。

あなたはそれらを短絡演算子と考えることができます:

  • all(array)配列内のすべての値を調べ、提供された演算子を使用してそれぞれを参照値と比較します。比較の結果が得られるとすぐfalseに、プロセスはfalseで終了します。それ以外の場合はtrueです。(論理短絡に匹敵しandます。)
  • any(array)配列内のすべての値を調べ、提供された演算子を使用してそれぞれを参照値と比較します。比較の結果が得られるとすぐtrueに、プロセスはtrueで終了し、それ以外の場合はfalseで終了します。(論理短絡に匹敵しorます。)

これが3 <> any('{1,2,3}')、望ましい結果が得られない理由です。プロセスは、不等式について3と1を比較します。これは真であり、すぐに真を返します。条件全体を真にするには、配列内の3とは異なる単一の値で十分です。最後の配列位置の3はprobです。使われたことがない。

3 <> all('{1,2,3}')一方、すべての値が3に等しくないことを確認します。falseを生成する要素(この場合は最後)までtrueを生成するすべての比較を実行し、全体的な結果としてfalseを返します。これはOPが望んでいることです。

于 2018-05-03T15:14:05.567 に答える
25

NULLに注意してください

両方ALL

(some_value != ALL(some_array))

そしてANY

NOT (some_value = ANY(some_array))

some_arraynullでない限り機能します。配列がnullの可能性がある場合は、coalesce()で説明する必要があります。

(some_value != ALL(coalesce(some_array, array[]::int[])))

または

NOT (some_value = ANY(coalesce(some_array, array[]::int[])))

ドキュメントから:

配列式がnull配列を生成する場合、ANYの結果はnullになります

配列式がnull配列を生成する場合、ALLの結果はnullになります

于 2018-03-01T02:21:50.887 に答える
14

アップデート:

postgres 9.3の時点で、

(contains演算子)NOTと組み合わせて使用​​して、これを実現することもできます。@>

IE。

SELECT COUNT(*) FROM "messages" WHERE NOT recipient_ids @> ARRAY[3];

于 2017-04-12T22:13:38.250 に答える
13

not (3 = any(recipient_ids))

于 2012-07-30T22:44:50.827 に答える
3

ANY/ALL演算子は配列インデックスでは機能しないことに注意してください。インデックスを念頭に置いている場合:

SELECT COUNT(*) FROM "messages" WHERE 3 && recipient_ids

とネガティブ:

SELECT COUNT(*) FROM "messages" WHERE NOT (3 && recipient_ids)

次に、次のようにインデックスを作成できます。

CREATE INDEX recipient_ids_idx on tableName USING GIN(recipient_ids)
于 2014-06-20T14:56:23.037 に答える