如何在 PostgreSQL 中 select 时将 json 数组中的所有键提取到列中
how to extract all keys in json array into column when select in PostgreSQL
我使用的是 PostgreSQL 版本 12.9
我有一个名为 EmployeeFamily
的 Table
并且 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)
第一步,你应该知道这个数据库中的命名是小写的。
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)
我使用的是 PostgreSQL 版本 12.9
我有一个名为 EmployeeFamily
的 Table
并且 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)
第一步,你应该知道这个数据库中的命名是小写的。
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)