PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

PostgreSQL 9.4:Aggregat/Join-Tabelle auf JSON-Feld-ID innerhalb des Arrays

Die Grundidee ist, dass Ihre Abfrage erwarten sollte, dass Ihr JSON auf eine bestimmte Weise strukturiert ist, sonst wird es wirklich komplex. Basierend auf der erwarteten Struktur können wir die JSON-Struktur mit json_to_recordset in Spalten zerlegen und mit zusätzlichen Informationen mithilfe von json_build_object neu zu erstellen und 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

Das funktioniert, ist aber in Bezug auf die Flexibilität sehr eingeschränkt:Ich muss jedes Feld Ihrer Registerkarten und Eigenschaften explizit auflisten und erwarte, dass das Dokument eine bestimmte Struktur hat. Aber es ist ein guter Anfang :)