sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur man frågar jsonb-arrayer med IN-operator

Kort svar

Du kan använda funktionen jsonb_array_elements() i en lateral sammanfogning och använd dess resultat value i komplexa uttryck i WHERE klausul:

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

Distinkt

Frågan kan returnera dubblerade rader när filtervillkoren är uppfyllda i mer än ett element i arrayen i en enda rad, t.ex.

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)    

Därför kan det vara rimligt att använda DISTINCT i SELECT lista:

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

eller EXISTS i WHERE klausul, som kan vara lite snabbare:

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

Du kan också välja matchande matriselement i de fall då denna information behövs:

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)

Prestanda

jsonb_array_elements() funktionen är dyr. För större tabeller kan användningen av funktionen vara tveksam på grund av stor serverbelastning och den långa exekveringstiden för en fråga.

Medan ett GIN-index kan användas för frågor med @> operatör:

CREATE INDEX ON test USING GIN (test_content)

i fallet med funktionen är detta inte möjligt. Frågor som stöds av indexet kan vara upp till flera dussin gånger snabbare än de som använder funktionen.




  1. Primärnyckel SQL-handledning – Hur man definierar en primärnyckel i en databas

  2. Säkerhetskopiera en enda tabell med dess data från en databas i sql server 2008

  3. JSON_KEYS() – Returnera nycklarna från ett JSON-objekt i MySQL

  4. Hur man använder mallar i SQL Server Management Studio (SSMS) - SQL Server / TSQL självstudie del 16