如何在 PostgreSQL 中 select 时将 json 数组中的所有键提取到列中

how to extract all keys in json array into column when select in PostgreSQL

我使用的是 PostgreSQL 版本 12.9

我有一个名为 EmployeeFamilyTable 并且 family 列的类型为 jsonb

EmployeeFamily table如下:

id first_name last_name family
1 A1 B1 [{"name":"C1","role":"Father"},{"name":"D1","role":"Mother"},{"name":"E1","role":"Brother"}]
2 A2 B2 [{"name":"C2","role":"Father"},{"name":"D2","role":"Mother"},{"name":"F2","role":"Sister"}]

现在我想要一个具有以下结果的查询:

id first_name last_name family_name role
1 A1 B1 C1 Father
2 A1 B1 D1 Mother
3 A1 B1 E1 Brother
4 A2 B2 C2 Father
5 A2 B2 D2 Mother
6 A2 B2 F2 Sister

帮我用这个结果写查询!

谢谢大家

可以使用jsonb_array_elements展开jsonb数组
然后从家庭成员那里获取字段。

select emp.id, emp.first_name, emp.last_name
, fam.member->>'name' as family_name
, fam.member->>'role' as role
from EmployeeFamily emp
cross join lateral jsonb_array_elements(emp.family) fam(member)
id first_name last_name family_name role
1 A1 B1 C1 Father
1 A1 B1 D1 Mother
1 A1 B1 E1 Brother
2 A2 B2 C2 Father
2 A2 B2 D2 Mother
2 A2 B2 F2 Sister

db<>fiddle here

上测试

一个选项是 jsonb_to_recordset() 函数以取消嵌套对象数组,例如

SELECT ROW_NUMBER() OVER (ORDER BY id, name ) AS id,
       first_name, last_name, name AS family_name, role
  FROM EmployeeFamily,
       jsonb_to_recordset(family) AS (name TEXT, role TEXT)

Demo

第一步,你应该知道这个数据库中的命名是小写的。
jsonb 以分解后的二进制形式存储数据;也就是说,不是 ASCII/UTF-8 字符串,而是二进制代码。
总结:

SELECT
    e.ID,
    e.first_name,
    e.last_name,
    j.MEMBER -> 'role' AS ROLE,
    j.MEMBER -> 'name' AS NAME 
FROM
    employeefamily e
    CROSS JOIN jsonb_array_elements (e.FAMILY) j(MEMBER)