返回嵌套聚合和正确的结果集

时间:2017-04-28 02:22:03

标签: postgresql

我做了一件小事,让事情变得更轻松:https://www.db-fiddle.com/f/5ELU6xinJrXiQJ6u6VH5/3

我有一张交易表。交易可能有很多属性。交易或财产可能有很多领域。我编写了一个聚合所有属性,交易字段和属性字段的查询,并在每行中返回它们。我希望在属性聚合列中返回每个属性字段。

目前,结果集中存在错误,现在结构就是我想要的。

例如,在我上面链接的小提琴中,第一行在属性列中返回:

[{
    "id": 1,
    "deal_id": 1,
    "address": "123 Fake Street"
}, {
    "id": 1,
    "deal_id": 1,
    "address": "123 Fake Street"
}]

它应该返回:

[{
    "id": 1,
    "deal_id": 1,
    "address": "123 Fake Street"
}, {
    "id": 2,
    "deal_id": 1,
    "address": "456 Fake Street"
}]

除了返回正确的结果集之外,我还希望将属性字段嵌套在结果集中。像这样:

[
  {
    "id": 1,
    "deal_id": 1,
    "address": "123 Fake Street",
    "fields": [
      {
        "id": 2,
        "parent": "property",
        "parent_id": 1,
        "key": "Square Feet",
        "value": "10,000"
      },
      {
        "id": 3,
        "parent": "property",
        "parent_id": 1,
        "key": "Maximum Occupancy",
        "value": "150"
      }
    ]
  },
  {
    "id": 2,
    "deal_id": 1,
    "address": "456 Fake Street",
    "fields": [
      {
        "id": 4,
        "parent": "property",
        "parent_id": 1,
        "key": "Square Feet",
        "value": "12,000"
      },
      {
        "id": 5,
        "parent": "property",
        "parent_id": 1,
        "key": "Maximum Occupancy",
        "value": "175"
      }
    ]    
  }
]

我被困住了,希望得到任何帮助

1 个答案:

答案 0 :(得分:1)

你必须做一些嵌套来实现这个目标:

with properties as (
    select 
        properties.*, 
        json_agg(property_fields.*) as property_fields 
    from 
        properties 
    left join fields as property_fields 
        on property_fields.parent = 'property' and property_fields.parent_id = properties.id 
    group by properties.id, properties.deal_id, properties.address
)
select 
    deals.*, 
    json_agg(properties.*) as deal_properties, 
    json_agg(deal_fields.*) as deal_fields
from deals

left join properties on deals.id = properties.deal_id
left join fields deal_fields on deal_fields.parent = 'deal' and deal_fields.parent_id = deals.id

group by deals.id, deals.name;

注意:

1)您必须将PK添加到您的id列。如果是这样,您不需要按表格中的所有列进行分组,例如:group by deals.id,deals.name,just group by deals.id;嵌套属性表也是如此。

2)您可以使用json_agg而不是数组函数

3)您可能必须在两列上的字段表上创建复合btree索引:parent + parent_id。

4)经验法则:你必须拥有尽可能多的" WITH"子查询尽可能深的是你的结果集。