【问题标题】:How can I return an ARRAY/JSON structure in a column in postgresql?如何在 postgresql 的列中返回 ARRAY/JSON 结构?
【发布时间】:2020-11-10 17:19:21
【问题描述】:

您好,我有一组表格如下,用一个最小的示例来解释我的问题(我想知道如何检索该结构,而不是更改数据库结构):

fruit: 
id | name | form| texture_id
-------------------------------
1 | Apple | round | 1
2 | Banana | long | 1

fruit_varieties: 
id | name | fruit_id | color
-------------------------------
1 | golden   | 1| green
2 | fuji     | 1| red
3 | canarias | 2| yellow

fruit_texture
id | name
-------------------------------
1 | soft
2 | hard
variety_countries
id | name | fruit_variety_id | average_temperature
-------------------------------
1 | france | 1 | 21
2 | spain | 1  | 24
3 | italy | 2  | 23

我想得到这个结构如下: 对于给定的fruit.name=Apple

{
    "fruit_name" = "Apple",
    "form" = "round",
    "texture" = "soft",
    "fruit_properties" = [{
            "variety_name" = "Golden",
            "color" = "green",
            "countries" = [{
                    "country" = "france",
                    "avg_temperature" = "21",
                }, {
                    "country" = "spain",
                    "avg_temperature" = "24",
                }
            ]
        }, {
            "variety_name" = "fuji",
            "color" = "red",
            "countries" = [{
                    "country" = "italy",
                    "avg_temperature" = "23",
                }
            ]
        }
    ]
}

所以我从这样的事情开始

SELECT 
fruit.name AS fruit_name,
fruit.form AS form,
fruit_texture.name AS texture,
(
    # I don't know how to handle this
) AS fruit_properties
FROM fruit
JOIN fruit_varieties
ON fruit.id = fruit_varieties.fruit_id
WHERE fruit.name = 'Apple'

现在我不知道如何在列中返回该数组,或创建包含整个响应的 JSON。我已经尝试使用一些 JSON PATH 函数已经有几个小时了

有人可以用这个简单的例子给我一个提示吗?

【问题讨论】:

    标签: sql arrays json postgresql subquery


    【解决方案1】:

    您的输出结构不是标准的 JSON 格式。键和值之间应该是: 而不是=。考虑到您想要标准 JSON 输出,请尝试下面提到的查询:

    select row_to_json(d2) from (
    select
    name,
    form,
    texture,
    json_agg(json_build_object('variety_name',variety_name,'color',color,'countries',countries)) "fruit_properties"
    from 
    (
    select 
    t1.name "name",
    t1.form "form",
    t3.name "texture",
    t2.name "variety_name",
    t2.color "color",
    json_agg(json_build_object( 'country',t4.name,'temp',t4.average_temperature)) "countries"
    from 
    fruit t1 inner join fruit_varieties t2 on t1.id=t2.fruit_id
    inner join fruit_texture t3 on t1.texture_id=t3.id
    inner join variety_countries  t4 on t4.fruit_variety_id=t2.id
    group by 1,2,3,4,5
    ) d1
    group by 1,2,3
    ) d2
    where d2.name='Apple'
    
    

    DEMO

    如果您不使用 where 子句,上述查询将为每个水果返回一个带有 JSON 值的行。

    如果您确实想要问题中提到的输出,请在上述查询中将 row_to_json(d2) 替换为 replace(row_to_json(d2)::text,':', ' = ')

    【讨论】:

    • 谢谢你解决了这个问题,但现在我试图在我的项目中做同样的事情,我需要更深入地了解结构,例如有一个要从 fruit_varieties 调用的表有一个带有names 的颜色表并将其与color_id 链接起来,可能有多个颜色。我已尝试扩展此查询,但出现错误 aggregate function calls cannot be nested
    • 只需在您的问题中添加示例即可。我会相应地更新答案。从您的错误来看,您似乎试图在其中调用 json_agg。
    • 我扩展了问题,将另一个表嵌套在另一个嵌套数组中。我认为这个例子说明了我的问题
    • @nck 根据您的新要求更新了答案。请注意,您需要为每个嵌套数组编写子查询
    • @Akhilesh Mishra 非常感谢它有效,我从来没有想过这个解决方案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-28
    • 2020-11-05
    • 2017-01-26
    • 2017-09-10
    • 2021-04-13
    • 1970-01-01
    • 2018-08-04
    相关资源
    最近更新 更多