Apakah cara postgres menggabungkan IS DISTINCT FROM
dengan ANY
atau cara lain yang rapi untuk mendapatkan hasil yang sama?
select count(*)
from (select 'A' foo union all select 'Z' union all select null) z
where foo <> any(array[null, 'A']);
count
-------
1
(1 row)
select count(*)
from (select 'A' foo union all select 'Z' union all select null) z
where foo is distinct from any(array[null, 'A']);
ERROR: syntax error at or near "any"
LINE 3: where foo is distinct from any(array[null, 'A']);
^
postgresql
null
postgresql-9.3
Jack berkata coba topanswers.xyz
sumber
sumber
IS DISTINCT FROM
operator? Sepertinya hanya keterbatasan teknis pengurai daripada masalah semantik.Operator
Ini berdasarkan operator pintar @ Daniel .
Saat berada di sana, buat combo fungsi / operator menggunakan tipe polimorfik . Kemudian ia bekerja untuk semua jenis - seperti konstruksi.
Dan buat fungsinya
IMMUTABLE
.Pencarian cepat dengan symbolhound muncul kosong, sehingga operator
<!>
tampaknya tidak digunakan dalam modul apa pun.Jika Anda akan sering menggunakan operator ini, Anda dapat menyempurnakannya untuk membantu perencana kueri ( seperti saran kuda yang hilang dalam komentar ). Sebagai permulaan, Anda bisa menambahkan
COMMUTATOR
danNEGATOR
klausa untuk membantu pengoptimal kueri. GantiCREATE OPERATOR
dari atas dengan ini:Dan tambahkan:
Tetapi klausa tambahan tidak akan membantu dengan kasus penggunaan di tangan dan indeks polos masih tidak akan digunakan. Jauh lebih canggih untuk mencapainya. (Saya belum mencoba.) Baca bab "Informasi Optimalisasi Operator" di manual untuk detailnya.
Kasus cobaan
Kasus uji dalam pertanyaan hanya dapat berhasil jika semua nilai dalam array identik. Untuk larik dalam pertanyaan (
'{null,A}'::text[]
) hasilnya selalu BENAR. Apakah itu dimaksudkan? Saya menambahkan tes lain untuk "IS DISTINCT FROM ALL":Alternatif dengan operator standar
dapat hampir diterjemahkan ke
foo = ALL (test_arr)
hasil ...TRUE
.. jika semua elemen adalahfoo
FALSE
.. jika adaNOT NULL
elemen<> foo
NULL
.. jika setidaknya satu elemenIS NULL
dan tidak ada elemen<> foo
Jadi, kasing sudut yang tersisa adalah tempat
-
foo IS NULL
- dan
test_arr
terdiri dariNULL
elemen.Jika salah satu dari mereka dapat dikesampingkan, kita sudah selesai. Karena itu, gunakan tes sederhana jika
- kolom didefinisikan
NOT NULL
.- atau Anda tahu array tidak pernah semua NULL.
Selain itu, tes tambahan:
Di mana
'A'
dan'B'
bisa ada nilai yang berbeda. Penjelasan dan alternatif di bawah pertanyaan terkait ini pada SO:Apakah array semua NULL di PostgreSQL
Sekali lagi, jika Anda tahu tentang nilai apa pun yang tidak dapat ada
test_arr
, misalnya string kosong''
, Anda masih dapat menyederhanakan:Ini adalah matriks tes lengkap untuk memeriksa semua kombinasi:
Ini sedikit lebih bertele-tele daripada solusi Andriy
EXCEPT
, tetapi jauh lebih cepat.sumber
OPERATOR
, haruskahCOMMUTATOR
(danNEGATOR
, mungkin denganIS NOT DISTINCT FROM
operator terbalik ) diberikan? postgresql.org/docs/current/static/xoper-optimization.htmlapp_status <!> any(array[3,6])
. Sayangnya, itu tidak berpengaruh pada catatan. Apakah itu berfungsi dengan bilangan bulat?