查询列表中的 JSON 个对象 (Postgres 11)

Query JSON object within a list (Postgres 11)

我有一个存储 jsonb 的“contact_info”列,它看起来像这样:

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

我正在尝试检索 phone 数字等于“123-4567”的所有行。

如何在单行查询中执行此操作?我可以 return 整个列 SELECT contact_info FROM db_name.db_table; 但没有成功拉出单个对象并查询里面的 phone 数字。

我一直在看[这个问题][1],但它与我的情况略有不同(json 对象列表与包含列表的 json 对象),我可以不知道如何将解决方案应用于我的问题版本。

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

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'

请注意,如果给定数组中的多个对象与 phone 数字匹配,则此 returns 多行。如果你想避免这种情况,你可以使用子查询:

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'
)

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

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

Demo