J'ai une table Postgres dont le contenu est similaire à celui-ci:
id | data
1 | {"a":"4", "b":"5"}
2 | {"a":"6", "b":"7"}
3 | {"a":"8", "b":"9"}
La première colonne est un entier et la seconde est une colonne json.
Je veux pouvoir développer les clés et les valeurs du json pour que le résultat ressemble à ceci:
id | key | value
1 | a | 4
1 | b | 5
2 | a | 6
2 | b | 7
3 | a | 8
3 | b | 9
Cela peut-il être réalisé dans Postgres SQL?
Ce que j'ai essayé
Étant donné que le tableau d'origine peut être simulé en tant que tel:
select *
from
(
values
(1, '{"a":"4", "b":"5"}'::json),
(2, '{"a":"6", "b":"7"}'::json),
(3, '{"a":"8", "b":"9"}'::json)
) as q (id, data)
Je peux obtenir uniquement les clés en utilisant:
select id, json_object_keys(data::json)
from
(
values
(1, '{"a":"4", "b":"5"}'::json),
(2, '{"a":"6", "b":"7"}'::json),
(3, '{"a":"8", "b":"9"}'::json)
) as q (id, data)
Et je peux les obtenir sous forme de records comme celui-ci:
select id, json_each(data::json)
from
(
values
(1, '{"a":"4", "b":"5"}'::json),
(2, '{"a":"6", "b":"7"}'::json),
(3, '{"a":"8", "b":"9"}'::json)
) as q (id, data)
Mais je ne peux pas trouver comment atteindre le résultat avec l'identifiant, la clé et la valeur.
Des idées?
Remarque: le vrai json avec lequel je travaille est beaucoup plus imbriqué que cela, mais je pense que cet exemple représente bien mon problème sous-jacent.
SELECT q.id, d.key, d.value
FROM q
JOIN json_each_text(q.data) d ON true
ORDER BY 1, 2;
La fonction json_each_text()
est une fonction renvoyant un ensemble, vous devez donc l'utiliser comme source de ligne. La sortie de la fonction est ici jointe latéralement à la table q
, ce qui signifie que pour chaque ligne de la table, chaque paire (key, value)
De la data
est jointe uniquement à cette ligne, de sorte que la relation entre la ligne d'origine et les lignes formées à partir de l'objet json
est conservée.
La table q
peut également être une sous-requête très compliquée (ou une clause VALUES
, comme dans votre question). Dans la fonction, la colonne appropriée est utilisée à partir du résultat de l'évaluation de cette sous-requête, vous n'utilisez donc qu'une référence à l'alias de la sous-requête et à la colonne (alias de) de la sous-requête.