Vous traitez le résultat de la première jointure comme JSON, pas comme une chaîne de texte, utilisez donc jsonb_each()
au lieu de jsonb_each_text()
:
SELECT t.employee, json_object_agg(a.k, d.value) AS sales
FROM mytable t
JOIN LATERAL jsonb_each(t.data) a(k,v) ON a.k LIKE 'sales_%'
JOIN LATERAL jsonb_to_recordset(a.v) d(yr text, value float) ON d.yr = '2012'
WHERE t.employee = 'Jim' -- works because employee is unique
GROUP BY 1;
GROUP BY 1
est un raccourci pour GROUP BY t.employee
.
Résultat :
employee | sales
---------+--------
Jim | '{ "sales_tv" : 40, "sales_radio" : 76 }'
J'ai également démêlé et simplifié votre requête.
json_object_agg()
joue un rôle déterminant dans l'agrégation des paires nom/valeur en tant qu'objet JSON. Caster éventuellement en jsonb
si vous en avez besoin - ou utilisez jsonb_object_agg()
dans Postgres 9.5 ou version ultérieure.
Utilisation explicite de JOIN
syntaxe pour attacher les conditions à leur place la plus évidente.
Idem sans JOIN
explicite syntaxe :
SELECT t.employee, json_object_agg(a.k, d.value) AS sales
FROM mytable t
, jsonb_each(t.data) a(k,v)
, jsonb_to_recordset(a.v) d(yr text, value float)
WHERE t.employee = 'Jim'
AND a.k LIKE 'sales_%'
AND d.yr = '2012'
GROUP BY 1;