PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Как да заявя jsonb масиви с IN оператор

Кратък отговор

Можете да използвате функцията jsonb_array_elements() в странично съединение и използвайте неговия резултат value в сложни изрази в WHERE клауза:

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

Различими

Заявката може да върне дублирани редове, когато условията за филтриране са изпълнени в повече от един елемент от масива в един ред, напр.

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)    

Следователно може да е разумно да използвате DISTINCT в SELECT списък:

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

или EXISTS в WHERE клауза, която може да е малко по-бърза:

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

Можете също да изберете съответстващи елементи на масива в случаите, когато е необходима тази информация:

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)

Изпълнение

jsonb_array_elements() функцията е скъпа. За по-големи таблици използването на функцията може да бъде под въпрос поради голямото натоварване на сървъра и дългото време за изпълнение на заявка.

Докато GIN индекс може да се използва за заявки с @> оператор:

CREATE INDEX ON test USING GIN (test_content)

в случай на функция това не е възможно. Заявките, поддържани от индекса, могат да бъдат до няколко десетки пъти по-бързи от тези, използващи функцията.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ActiveRecord::StatementInvalid:PG InFailedSqlTransaction

  2. PostgreSQL работи бавно? Съвети и трикове, за да стигнете до източника

  3. Как да конвертирате низов случай в PostgreSQL

  4. Актуализации на инструментите за тестване на PostgreSQL с архив за сравнителни показатели

  5. Пазете PostgreSQL понякога да избира лош план за заявка