sql >> Databáze >  >> RDS >> PostgreSQL

Jak dotazovat pole jsonb pomocí operátoru IN

Krátká odpověď

Můžete použít funkci jsonb_array_elements() v bočním spojení a použijte jeho výsledek value ve složitých výrazech v WHERE klauzule:

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

Odlišné

Dotaz může vracet duplicitní řádky, pokud jsou splněny podmínky filtru ve více než jednom prvku pole v jednom řádku, např.

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)    

Proto může být rozumné použít DISTINCT v SELECT seznam:

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

nebo EXISTS v WHERE klauzule, která může být o něco rychlejší:

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

Můžete také vybrat odpovídající prvky pole v případech, kdy jsou tyto informace potřeba:

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)

Výkon

jsonb_array_elements() funkce je drahá. U větších tabulek může být použití funkce sporné kvůli velkému zatížení serveru a dlouhé době provádění dotazu.

Zatímco index GIN lze použít pro dotazy s @> operátor:

CREATE INDEX ON test USING GIN (test_content)

v případě funkce to není možné. Dotazy podporované indexem mohou být až několik desítekkrát rychlejší než dotazy využívající tuto funkci.




  1. Nástroj ADODFCMP

  2. Kdy mám zavřít DatabaseHelper?

  3. Chyba přihlášení k serveru SQL:přihlášení se nezdařilo pro uživatele 'NT AUTHORITY\SYSTEM'

  4. MySQL CONVERT_TZ()