如何将多个postgreSQL表嵌套到一个json中?
我刚开始使用postgreSQL,现在我正在尝试获取相关表项的树结构 例如,我有以下表格: 街道、物业、建筑物、楼层、房间如何将多个postgreSQL表嵌套到一个json中?,json,postgresql,Json,Postgresql,我刚开始使用postgreSQL,现在我正在尝试获取相关表项的树结构 例如,我有以下表格: 街道、物业、建筑物、楼层、房间 streets (columns: id, name) properties (columns: id, name, street_id) buildings (columns: id, name, property_id) floors (columns: id, name, building_id) rooms (columns: id, name, floor_id)
streets (columns: id, name)
properties (columns: id, name, street_id)
buildings (columns: id, name, property_id)
floors (columns: id, name, building_id)
rooms (columns: id, name, floor_id)
现在我尝试获得如下输出:
[{
"id":1,
"name":"Main Street",
"properties": [{
"id":"1",
"name":"First Property",
"buildings": [{
"id":"1",
"name":"Main Building",
"floors": [{...},{...}]
},{
"id":"2",
"name":"Shed",
"floors": [{...},{...}]
}]
},{
"id":"2",
"name":"Another Property",
"buildings": [{...},{...}]
}]
}]
目前的查询如下:
SELECT s.*, json_agg(p.*) as properties
FROM streets AS s
INNER JOIN properties AS p ON s.id = p.street_id
GROUP BY s.id;
这为我提供了上述两层街道的输出以及街道内的属性结果。但是我不知道如何将建筑物嵌套到物业中,然后将楼层嵌套到建筑物中
我可以为它们添加另一个内部连接和json_agg(),但是它们不会在属性中
有什么建议我应该如何处理这个问题吗
编辑:
谢谢,德米特里,你的回答很好。但是现在让我们假设我想将所有数据存储在同一个名为“locations”的表中,并通过“parent_id”链接条目
因此,我有以下专栏:
id、名称、类型、父\u id
使用下面的代码,我得到了错误的层次结构
WITH RECURSIVE locationtree AS (
SELECT
e.*,
null::json as parent
FROM location e
WHERE parent_id IS NULL
UNION ALL
SELECT
e.*,
row_to_json(et.*) as parent
FROM location e
INNER JOIN locationtree et
ON et.id = e.parent_id
)
SELECT *
FROM locationtree;
这导致
房间
地板
建筑
财产
街头
但我想像最初的问题和Dmitry的回答一样
街道
性质
建筑
地板
房间
关于使用表达式查询的任何建议如下所示:
WITH floors_agg AS (
-- get floors with nested rooms
SELECT
f.*,
json_agg(r.*) nested_rooms
FROM floors f
LEFT JOIN rooms r ON r.floor_id = f.id
GROUP BY 1
), buildings_agg AS (
-- get buildings with nested floors
SELECT
b.*,
json_agg(fa.*) nested_floors
FROM buildings b
LEFT JOIN floors_agg fa ON fa.building_id = b.id
GROUP BY 1
), properties_agg AS (
-- get properties with nested buildings
SELECT
p.*,
json_agg(ba.*)
FROM properties p
LEFT JOIN buildings_agg ba ON ba.property_id = p.id
GROUP BY 1
), streets_agg AS (
-- get streets with nested properties
SELECT
s.*,
json_agg(pa.*) nested_properties
FROM streets s
LEFT JOIN properties_agg pa ON pa.street_id = s.id
ORDER BY 1
)
SELECT json_agg(sa.*)
FROM streets_agg sa;
使用表达式,查询可能如下所示:
WITH floors_agg AS (
-- get floors with nested rooms
SELECT
f.*,
json_agg(r.*) nested_rooms
FROM floors f
LEFT JOIN rooms r ON r.floor_id = f.id
GROUP BY 1
), buildings_agg AS (
-- get buildings with nested floors
SELECT
b.*,
json_agg(fa.*) nested_floors
FROM buildings b
LEFT JOIN floors_agg fa ON fa.building_id = b.id
GROUP BY 1
), properties_agg AS (
-- get properties with nested buildings
SELECT
p.*,
json_agg(ba.*)
FROM properties p
LEFT JOIN buildings_agg ba ON ba.property_id = p.id
GROUP BY 1
), streets_agg AS (
-- get streets with nested properties
SELECT
s.*,
json_agg(pa.*) nested_properties
FROM streets s
LEFT JOIN properties_agg pa ON pa.street_id = s.id
ORDER BY 1
)
SELECT json_agg(sa.*)
FROM streets_agg sa;
哇,这正是我想要的。现在看起来很容易……)但假设现在我将所有数据存储在同一个表中,表中有父id,因此街道、物业、建筑物、楼层、房间都存储在一个名为location的表中,表中有“id”、“name”、“type”、“parent\u id”列。我将如何获取该树?@sking
街道与agg
(或最初定义的表)之间的关系是什么和位置
表格location.id=streets.location\u id
?我不知道你的意思。我的第二个问题是,当我将所有信息存储在一个表中时,如何获得与您的结果相同的输出。因此,我会删除街道、物业、建筑物、楼层、房间等表格,而是创建一个具有位置的新表格。这将包含所有街道、建筑物、财产、楼层和房间名称。。所以条目应该是{ID:1,name:Main Street,type:Street,parent_ID:null}{ID:2 name:school ground,type:property,parent_ID:1}….哇,这就是我想要的。现在看起来很容易……)但假设现在我将所有数据存储在同一个表中,表中有父id,因此街道、物业、建筑物、楼层、房间都存储在一个名为location的表中,表中有“id”、“name”、“type”、“parent\u id”列。我将如何获取该树?@sking街道与agg
(或最初定义的表)之间的关系是什么和位置
表格location.id=streets.location\u id
?我不知道你的意思。我的第二个问题是,当我将所有信息存储在一个表中时,如何获得与您的结果相同的输出。因此,我会删除街道、物业、建筑物、楼层、房间等表格,而是创建一个具有位置的新表格。这将包含所有街道、建筑物、财产、楼层和房间名称。。所以条目应该是{ID:1,name:Main Street,type:Street,parent_ID:null}{ID:2 name:school ground,type:property,parent_ID:1}。。。。