du måste unest arrayen av json-objekt först med funktionen (json_array_elements
eller jsonb_array_elements
om du har jsonb-datatypen ), så kan du komma åt värdena genom att ange nyckeln.
WITH json_test (col) AS (
values (json '[{"name":"Mickey Mouse","age":10},{"name":"Donald Duck","age":5}]')
)
SELECT
y.x->'name' "name"
FROM json_test jt,
LATERAL (SELECT json_array_elements(jt.col) x) y
-- outputs:
name
--------------
"Mickey Mouse"
"Donald Duck"
För att få ett antal unika namn är det en fråga som liknar ovanstående, förutom att funktionen count distinct aggregat tillämpas på y.x->>name
WITH json_test (col) AS (
values (json '[{"name":"Mickey Mouse","age":10},{"name":"Donald Duck","age":5}]')
)
SELECT
COUNT( DISTINCT y.x->>'name') distinct_names
FROM json_test jt,
LATERAL (SELECT json_array_elements(jt.col) x) y
Det är nödvändigt att använda ->>
istället för ->
som den förra (->> ) kastar det extraherade värdet som text, vilket stöder jämställdhetsjämförelse (behövs för distinkt räkning), medan det senare (
-> ) extraherar värdet som json, vilket inte stöder jämställdhetsjämförelse.
Alternativt kan du konvertera json
som jsonb
och använd jsonb_array_elements
. JSONB
stöder jämställdhetsjämförelsen, så det är möjligt att använda COUNT DISTINCT tillsammans med extraktion via ->
, dvs.
COUNT(DISTINCT (y.x::jsonb)->'name')