Saya menggunakan tipe array asli Postgres, dan mencoba menemukan catatan di mana ID tidak ada dalam ID penerima array.
Saya dapat menemukan di mana mereka DI:
SELECT COUNT(*) FROM messages WHERE (3 = ANY (recipient_ids))
Tapi ini tidak berhasil:
SELECT COUNT(*) FROM messages WHERE (3 != ANY (recipient_ids))
SELECT COUNT(*) FROM messages WHERE (3 = NOT ANY (recipient_ids))
Bagaimana cara yang tepat untuk menguji kondisi ini?
arrays
postgresql
pengguna577808
sumber
sumber
WHERE 3 NOT IN recipient_ids
bekerja?text[]
danint[]
array:select not(array[1,2,3] @> array[3]);
null
kolom berisi atau tidak terdapat dalam array, itu akan selalu mengatakan tidak. Butuh waktu 20 menit untuk men-debug beberapa metode yang berisi untuk sampai pada kesimpulan bahwa Anda tidak dapat memeriksa apakah null terdapat dalam arrayJawaban:
SELECT COUNT(*) FROM "messages" WHERE NOT (3 = ANY (recipient_ids))
Anda selalu dapat meniadakan
WHERE (condition)
denganWHERE NOT (condition)
sumber
ANY
alih-alihIN
saat daftarrecipient_ids
input Anda bertambah: stackoverflow.com/questions/1009706/…Anda dapat memutarnya sedikit dan mengatakan "3 tidak sama dengan semua ID":
Dari manual yang bagus :
sumber
any
tidak berhasil dalam kasus iniany
danall
di doc postgres, yang mengatakan: "x <> ANY (a,b,c)
setara denganx <> a OR <> b OR x <> c
". ref: postgresqltutorial.com/postgresql-any postgresqltutorial.com/postgresql-allMenambah
ALL/ANY
JawabanSaya lebih suka semua solusi yang menggunakan
all
atauany
untuk mencapai hasil, menghargai catatan tambahan (misalnya tentang NULL s). Sebagai tambahan lainnya, berikut adalah cara untuk memikirkan operator tersebut.Anda dapat menganggapnya sebagai operator hubung singkat :
all(array)
menelusuri semua nilai dalam larik, membandingkan masing-masing dengan nilai referensi menggunakan operator yang disediakan. Begitu perbandingan menghasilkanfalse
, proses berakhir dengan salah, jika tidak benar. (Sebanding dengan logika hubung singkatand
.)any(array)
menelusuri semua nilai dalam larik, membandingkan masing-masing dengan nilai referensi menggunakan operator yang disediakan. Segera setelah hasil perbandingantrue
, proses berakhir dengan benar, sebaliknya salah. (Sebanding dengan logika hubung singkator
.)Inilah sebabnya mengapa
3 <> any('{1,2,3}')
tidak menghasilkan hasil yang diinginkan: Proses membandingkan 3 dengan 1 untuk ketidaksetaraan, yang benar, dan segera mengembalikan benar. Nilai tunggal dalam larik yang berbeda dari 3 sudah cukup untuk membuat seluruh ketentuan menjadi benar. Angka 3 pada posisi larik terakhir adalah prob. tidak pernah dipakai.3 <> all('{1,2,3}')
di sisi lain memastikan semua nilai tidak sama 3. Ini akan berjalan melalui semua perbandingan yang menghasilkan true hingga elemen yang menghasilkan false (yang terakhir dalam kasus ini), untuk mengembalikan false sebagai hasil keseluruhan. Inilah yang diinginkan OP.sumber
not (3 = any(recipient_ids))
?sumber
3 <> ANY(ARRAY[1,2,3,4])
. Seharusnya bekerja seperti itu: \Sebuah pembaharuan:
pada postgres 9.3,
Anda dapat menggunakan
NOT
bersama-sama dengan@>
(berisi operator) untuk mencapai ini juga.YAITU.
SELECT COUNT(*) FROM "messages" WHERE NOT recipient_ids @> ARRAY[3];
sumber
Waspadalah terhadap NULL
Keduanya
ALL
:Dan
ANY
:Akan bekerja selama
some_array
tidak null. Jika array mungkin null, maka Anda harus memperhitungkannya dengan coalesce (), misalnyaAtau
Dari dokumen :
sumber
Perhatikan bahwa operator ANY / ALL tidak akan bekerja dengan indeks array. Jika indeks dalam pikiran:
SELECT COUNT(*) FROM "messages" WHERE 3 && recipient_ids
dan negatif:
SELECT COUNT(*) FROM "messages" WHERE NOT (3 && recipient_ids)
Indeks kemudian dapat dibuat seperti:
CREATE INDEX recipient_ids_idx on tableName USING GIN(recipient_ids)
sumber
&&
SELECT COUNT(*) FROM "messages" WHERE ARRAY[3] && recipient_ids
.