web-dev-qa-db-fra.com

Postgres GROUP BY sur champ intérieur jsonb

J'utilise Postgresql 9.4 et j'ai une table test, avec id::int et content::jsonb, comme suit:

 id |     content
----+-----------------
  1 | {"a": {"b": 1}}
  2 | {"a": {"b": 1}}
  3 | {"a": {"b": 2}}
  4 | {"a": {"c": 1}}

Comment puis-je GROUP BY sur un champ intérieur dans la colonne content et retourner chaque groupe sous forme de tableau? Plus précisément, les résultats que je recherche sont:

             content
---------------------------------
[{"a": {"b": 1}},{"a": {"b": 1}}]
[{"a": {"b": 2}}]
(2 rows)

En essayant:

SELECT json_agg(content) as content FROM test GROUP BY content ->> '{a,b}';

Rendements:

                               content
----------------------------------------------------------------------
[{"a": {"b": 1}}, {"a": {"b": 1}}, {"a": {"b": 2}}, {"a": {"c": 1}}]
(1 row)
10
JGem

Vous devez utiliser le #>> opérateur au lieu de ->> lorsque l'opérande de droite est un chemin json. Essaye ça:

SELECT json_agg(content) as content FROM test GROUP BY content #>> '{a,b}';

Rendements:

              content
------------------------------------
 [{"a": {"c": 1}}]
 [{"a": {"b": 2}}]
 [{"a": {"b": 1}}, {"a": {"b": 1}}]
(3 rows)
8
redneb

Je pense que json_agg () n'est pas le meilleur choix pour l'utiliser ici, car cela concatène les valeurs de contenu (l'ensemble des données json) dans un tableau pour un groupe spécifique.
Il est plus logique d'utiliser quelque chose comme ça (et j'ai ajouté 'count (*)', juste pour avoir un scénario plus courant):

SELECT content #>> '{a,b}' as a_b, count(*) as count FROM test GROUP BY content #>> '{a,b}';
1
user698116