Извлечение данных из Postgres DB в многоуровневую иерархическую структуру JSON - PullRequest
0 голосов
/ 24 апреля 2019

Я пытаюсь извлечь данные из базы данных postgres в файл JSON. Проблема здесь заключается в том, что мне нужно загрузить данные в виде нескольких иерархических файлов в файл JSON.

Любое решение для достижения этой цели в Postgres SQL-запрос или Python будет высоко ценится.

Я пытался сделать это на одном уровне и успешно выполнил запрос json_agg () на postgres, но не уверен, как это сделать для более чем 2 уровня.

Это мой почтовый индекс:

select
    json_build_object('column1',json_agg(
    json_build_object('name',column1,'column2',column2)))
     table1
from table;

which gives me :
[columns1:
{column2:value},
{column2:value2}
]

But what i need is:
eg: column1 column2 column3
    4       1       4
    4       4       5
    4       1       9
    2       3       7
    3       1       8
    1       1       1
    3       1       6

    output:
    [
    column1:4[{
      column2:1[{
        column3:4,
        colun3:9}]
    },
    { column2:4
      [{
        column3:5
      }]
    }]]

1 Ответ

0 голосов
/ 24 апреля 2019

Вот два разных варианта, потому что ваш вывод не является допустимым JSON, и поэтому немного сложно угадать, какой формат вы хотите:

Оба варианта ниже имеют одинаковую структуру запроса и просто различаются по тому, как онисоздайте объекты JSON.

Для большего количества уровней иерархии вам потребуется больше CTE, например agg_c3, или вы переписываете запрос, чтобы использовать вложенные вложенные элементы выбора, если предпочитаете (но которые труднее читать, чем CTE).

Значение ключа в оболочке

WITH
    my_table (col1, col2, col3) AS (
        VALUES (4,1,4), (4,4,5), (4,1,9), (2,3,7), (3,1,8), (1,1,1), (3,1,6)
    ),
    agg_c3 AS (
        SELECT col1, col2, jsonb_build_object('column3', jsonb_agg(jsonb_build_object('value', col3))) AS col3
        FROM my_table
        GROUP BY 1, 2
    ),
    agg_c2 AS (
        SELECT col1, jsonb_build_object('column2', jsonb_agg(jsonb_build_object('value', col2) || col3)) AS col2
        FROM agg_c3
        GROUP BY 1
    )
SELECT jsonb_build_object('column1', jsonb_agg(jsonb_build_object('value', col1) || col2)) AS json_object
FROM agg_c2
;

... возвращает:

{
  "column1": [
    {
      "value": 1,
      "column2": [
        {
          "value": 1,
          "column3": [
            {
              "value": 1
            }
          ]
        }
      ]
    },
    {
      "value": 3,
      "column2": [
        {
          "value": 1,
          "column3": [
            {
              "value": 8
            },
            {
              "value": 6
            }
          ]
        }
      ]
    },
    {
      "value": 2,
      "column2": [
        {
          "value": 3,
          "column3": [
            {
              "value": 7
            }
          ]
        }
      ]
    },
    {
      "value": 4,
      "column2": [
        {
          "value": 1,
          "column3": [
            {
              "value": 4
            },
            {
              "value": 9
            }
          ]
        },
        {
          "value": 4,
          "column3": [
            {
              "value": 5
            }
          ]
        }
      ]
    }
  ]
}

Только значения

WITH
    my_table (col1, col2, col3) AS (
        VALUES (4,1,4), (4,4,5), (4,1,9), (2,3,7), (3,1,8), (1,1,1), (3,1,6)
    ),
    agg_c3 AS (
        SELECT col1, col2, jsonb_agg(col3) AS col3
        FROM my_table
        GROUP BY 1, 2
    ),
    agg_c2 AS (
        SELECT col1, jsonb_agg(jsonb_build_object(col2::text, col3)) AS col2
        FROM agg_c3
        GROUP BY 1
    )
SELECT jsonb_agg(jsonb_build_object(col1::text, col2)) AS json_object
FROM agg_c2
;

... возвращает:

[
  {
    "1": [
      {
        "1": [
          1
        ]
      }
    ]
  },
  {
    "3": [
      {
        "1": [
          8,
          6
        ]
      }
    ]
  },
  {
    "2": [
      {
        "3": [
          7
        ]
      }
    ]
  },
  {
    "4": [
      {
        "1": [
          4,
          9
        ]
      },
      {
        "4": [
          5
        ]
      }
    ]
  }
]
...