PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

PostgreSQL 9.4 :table d'agrégation/jointure sur l'ID de champ JSON dans le tableau

L'idée de base est que votre requête doit s'attendre à ce que votre json soit structuré d'une certaine manière, sinon cela devient vraiment complexe. Sur la base de la structure attendue, nous sommes en mesure de disséquer la structure json en colonnes en utilisant json_to_recordset et de le reconstruire avec des informations supplémentaires en utilisant json_build_object et json_agg .

WITH tab_properties_with_expanded_data_type AS (
    SELECT
      content_type.id AS content_type_id,
      tab.name AS tab_name,
      json_agg(
          -- re-build the property object, but with additional data_type information
          json_build_object(
              'name', property.name,
              'order', property.order,
              'help_text', property.help_text,
              'description', property.description,
              'data_type', json_build_object('id', data_type.id, 'html', data_type.html)
          )
      ) AS tab_properties
    FROM content_type,
      json_to_recordset(content_type.tabs) AS tab(name TEXT, properties JSON),
      json_to_recordset(tab.properties) AS property(name TEXT, "order" INTEGER, help_text TEXT, description TEXT, data_type INTEGER)
      LEFT JOIN data_type ON data_type.id = property.data_type
    GROUP BY 
      content_type.id, 
      tab.name
)
SELECT
  tab_properties_with_expanded_data_type.content_type_id AS id, 
  json_agg(
      -- rebuild the tab object
      json_build_object(
          'name', tab_properties_with_expanded_data_type.tab_name,
          'properties', tab_properties_with_expanded_data_type.tab_properties
      )
  )
FROM tab_properties_with_expanded_data_type
GROUP BY 
  tab_properties_with_expanded_data_type.content_type_id

Cela fonctionne mais est très limité en termes de flexibilité :je dois lister explicitement chaque champ de vos onglets et propriétés et je m'attends à ce que le document ait une structure spécifique. Mais c'est un bon début :)