Ada dua varian IN
ekspresi:
expression IN (subquery)
expression IN (value [, ...])
Demikian pula, dua varian dengan ANY
membangun:
expression operator ANY (subquery)
expression operator ANY (array expression)
Subquery berfungsi untuk kedua teknik, tetapi untuk kedua bentuk masing-masing, IN
mengharapkan daftar nilai (sebagaimana didefinisikan dalam SQL standar) while = ANY
mengharapkan array .
Mana yang harus digunakan?
ANY
adalah tambahan yang lebih serbaguna, dapat dikombinasikan dengan operator biner mana pun yang mengembalikan nilai boolean. IN
terbakar menjadi kasus khusus ANY
. Faktanya, bentuk keduanya ditulis ulang secara internal:
IN
ditulis ulang dengan = ANY
NOT IN
ditulis ulang dengan <> ALL
Periksa EXPLAIN
output untuk permintaan apa pun untuk dilihat sendiri. Ini membuktikan dua hal:
IN
tidak pernah bisa lebih cepat dari= ANY
.= ANY
tidak akan jauh lebih cepat.
Pilihannya harus diputuskan oleh apa yang lebih mudah diberikan :daftar nilai atau larik (mungkin sebagai literal larik - nilai tunggal).
Jika ID yang akan Anda berikan berasal dari dalam DB lagi pula, jauh lebih efisien untuk memilihnya secara langsung (subquery) atau mengintegrasikan tabel sumber ke dalam kueri dengan JOIN
(seperti komentar @mu).
Untuk melewati daftar panjang nilai dari klien Anda dan dapatkan kinerja terbaik , gunakan larik, unnest()
dan gabungkan, atau berikan sebagai ekspresi tabel menggunakan VALUES
(seperti komentar @PinnyM). Tetapi perhatikan bahwa JOIN
mempertahankan kemungkinan duplikat dalam array / set yang disediakan saat IN
atau = ANY
tidak. Selengkapnya:
- Mengoptimalkan kueri Postgres dengan IN besar
Dengan adanya nilai NULL, NOT IN
seringkali pilihan yang salah dan NOT EXISTS
akan benar (dan juga lebih cepat):
- Pilih baris yang tidak ada di tabel lain
Sintaks untuk = ANY
Untuk ekspresi larik yang diterima Postgres:
- sebuah konstruktor array (array dibangun dari daftar nilai di sisi Postgres) dari formulir:
ARRAY[1,2,3]
- atau literal array dalam bentuk
'{1,2,3}'
.
Untuk menghindari jenis cast yang tidak valid, Anda dapat melakukan cast secara eksplisit:
ARRAY[1,2,3]::numeric[]
'{1,2,3}'::bigint[]
Terkait:
- PostgreSQL:Masalah dengan meneruskan array ke prosedur
- Cara meneruskan array tipe khusus ke fungsi Postgres
Atau Anda bisa buat fungsi Postgres dengan menggunakan VARIADIC
parameter, yang mengambil argumen individual dan membentuk larik darinya:
- Meneruskan beberapa nilai dalam satu parameter
Bagaimana cara melewatkan array dari Ruby?
Dengan asumsi id
menjadi integer
:
MyModel.where('id = ANY(ARRAY[?]::int[])', ids.map { |i| i})
Tapi saya hanya mencoba-coba di Ruby. @mu memberikan instruksi terperinci dalam jawaban terkait ini:
- Mengirim larik nilai ke kueri sql di ruby?