【问题标题】:Query JSON object within a list (Postgres 11)查询列表中的 JSON 对象 (Postgres 11)
【发布时间】:2020-11-29 23:49:16
【问题描述】:

我有一个存储 jsonb 的“contact_info”列,如下所示:

[ {"phoneNumber":"123-4567", "emailAddress":"email@address.com"} ]

我正在尝试检索电话号码等于“123-4567”的所有行。

如何在单行查询中做到这一点?我可以使用 SELECT contact_info FROM db_name.db_table; 返回整个列,但没有成功拉出单个对象并查询里面的电话号码。

我一直在查看 [this question][1] 但它与我的情况略有不同(json 对象列表与包含列表的 json 对象),我无法弄清楚如何将解决方案应用于我的问题版本。

【问题讨论】:

    标签: sql arrays json postgresql postgresql-11


    【解决方案1】:

    你可以使用JSONB_ARRAY_ELEMENTS()函数作为

    SELECT t.*
      FROM t
     CROSS JOIN JSONB_ARRAY_ELEMENTS(contact_info) AS js(elm)
     WHERE js.elm ->> 'phoneNumber' = '123-4567'
    

    Demo

    【讨论】:

    • 非常感谢!我最初并不确定这是如何工作的,而演示帮助我弄清楚了。
    【解决方案2】:

    如果您的所有数组都只有一个元素,这很简单:

    select t.*, t.contact_info -> 0 ->> 'emailAddress' as email_address
    from db_table t
    where t.contact_info -> 0 ->> 'phoneNumber' = '123-4567'
    

    否则,可以使用jsonb_array_elements() 和横向连接来取消嵌套数组,然后进行过滤:

    select t.*, x.obj ->> 'emailAddress' as email_address
    from db_table t
    cross join lateral jsonb_array_elements(t.contact_info) x(obj)
    where x.obj ->> 'phoneNumber' = '123-4567'
    

    请注意,如果给定数组中的多个对象与电话号码匹配,则会返回多行。如果你想避免这种情况,你可以使用子查询:

    select t.*, x.obj ->> 'emailAddress' as email_address
    from db_table t
    where exists (
        select 1
        from jsonb_array_elements(t.contact_info) x(obj)
        where x.obj ->> 'phoneNumber' = '123-4567'
    )
    

    【讨论】:

    • 感谢您的快速回复,我最终实现了下面的答案,但我非常感谢您的速度和答案的广度!
    猜你喜欢
    • 1970-01-01
    • 2015-08-11
    • 1970-01-01
    • 2018-09-17
    • 2015-07-03
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多