PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Bagaimana cara menanyakan array jsonb dengan operator IN

Jawaban singkat

Anda dapat menggunakan fungsi jsonb_array_elements() di gabung lateral dan gunakan hasilnya value dalam ekspresi kompleks di WHERE klausa:

SELECT t.* 
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('b', 'd')
AND value->>'label1' IN ('2', '3')

Berbeda

Kueri dapat mengembalikan baris duplikat saat kondisi filter terpenuhi di lebih dari satu elemen larik dalam satu baris, mis.

SELECT t.* 
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('a', 'b')

                  id                  |                          test_content                          
--------------------------------------+----------------------------------------------------------------
 aa82a8b8-33ef-4937-bd8c-8a4b40960f18 | [{"label": "a", "label1": "1"}, {"label": "b", "label1": "2"}]
 aa82a8b8-33ef-4937-bd8c-8a4b40960f18 | [{"label": "a", "label1": "1"}, {"label": "b", "label1": "2"}]
(2 rows)    

Oleh karena itu, mungkin masuk akal untuk menggunakan DISTINCT di SELECT daftar:

SELECT DISTINCT t.* 
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('a', 'b')

atau EXISTS di WHERE klausa, yang mungkin sedikit lebih cepat:

SELECT t.*
FROM test t
WHERE EXISTS (
    SELECT 
    FROM jsonb_array_elements(test_content)
    WHERE value->>'label' IN ('a', 'b')
    )

Anda juga dapat memilih elemen larik yang cocok jika informasi ini diperlukan:

SELECT id, value
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('a', 'b')

                  id                  |             value             
--------------------------------------+-------------------------------
 aa82a8b8-33ef-4937-bd8c-8a4b40960f18 | {"label": "a", "label1": "1"}
 aa82a8b8-33ef-4937-bd8c-8a4b40960f18 | {"label": "b", "label1": "2"}
(2 rows)

Kinerja

jsonb_array_elements() fungsi itu mahal. Untuk tabel yang lebih besar, penggunaan fungsi mungkin dipertanyakan karena beban server yang berat dan waktu eksekusi kueri yang lama.

Sedangkan indeks GIN dapat digunakan untuk query dengan @> operator:

CREATE INDEX ON test USING GIN (test_content)

dalam hal fungsi ini tidak mungkin. Kueri yang didukung oleh indeks bisa sampai beberapa lusin kali lebih cepat daripada yang menggunakan fungsi tersebut.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Catatan tentang Indeks B-Tree PostgreSQL

  2. Pernyataan yang Disiapkan tentang Postgresql di Rails

  3. Bagaimana Cosh() Bekerja di PostgreSQL

  4. Cara menggunakan array_agg() untuk varchar[]

  5. Pilih kueri dengan batas offset terlalu lambat