Вот два разных варианта, потому что ваш вывод не является допустимым 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
]
}
]
}
]