sql - 尝试构造 PostgreSQL 查询以从 JSON 中提取对象、数组、对象、数组、对象中的文本值
问题描述
我正在构建 PostgreSQL 系统和 SQL Server 系统之间的接口,并试图“扁平化” JSON 数据的结构以促进这一点。我在 SQL Server 方面非常有经验,但我对 PostgreSQL 和 JSON 都是新手。
JSON本质上包含两种类型的结构:type
“text”或“textarea”的结构,其中我想要的值在一个名为的对象中value
(下面的前两种情况),以及type
“select”的结构,其中value
对象指向一个id
对象较低级别的options
数组(下面的第三种情况)。
{
"baseGroupId": {
"fields": [
{
"id": "1f53",
"name": "Location",
"type": "text",
"options": [],
"value": "Over the rainbow"
},
{
"id": "b547",
"name": "Description",
"type": "textarea",
"options": [],
"value": "A place of wonderful discovery"
},
{
"id": "c12f",
"name": "Assessment",
"type": "select",
"options": [
{
"id": "e5fd",
"name": "0"
},
{
"id": "e970",
"name": "1"
},
{
"id": "0ff4",
"name": "2"
},
{
"id": "2db3",
"name": "3"
},
{
"id": "241f",
"name": "4"
},
{
"id": "3f52",
"name": "5"
}
],
"value": "241f"
}
]
}
}
眼尖的人会看到最后一个value
对象“241f”的值也可以在options
数组中针对其中一个id
对象看到。当像这样嵌套时,我需要提取相应的值name
,在本例中为“4”。
JSON 格式的信息位于表customfield字段textvalue中。它的数据类型是text但我将其强制为json。我最初在尝试在 WHERE 子句中应用条件时遇到数组设置错误,然后我阅读了有关使用 LATERAL 子查询的信息。它现在运行但返回所有选项,而不仅仅是匹配value
.
恐怕我无法让 SQL Fiddle 工作来重现我的结果,但我非常感谢检查我的查询以查看是否可以发现问题。
with cte_custombundledfields as
(
select
textvalue
, cfname
, json_array_elements(textvalue::json -> 'baseGroupId'->'fields') ->> 'name' as name
, json_array_elements(textvalue::json -> 'baseGroupId'->'fields') ->> 'value' as value
, json_array_elements(textvalue::json -> 'baseGroupId'->'fields') ->> 'type' as type
from
customfield
)
, cte_custombundledfieldsoptions as
(
select *
, json_array_elements(json_array_elements(textvalue::json -> 'baseGroupId'->'fields') -> 'options') ->> 'name' as value2
from
cte_custombundledfields x
, LATERAL json_array_elements(x.textvalue::json -> 'baseGroupId'->'fields') y
, LATERAL json_array_elements(y -> 'options') z
where
type = 'select'
and z ->> 'id' = x.value
)
select *
from
cte_custombundledfieldsoptions
解决方案
我发布了这个问题的简化版,由Bergi回答。
推荐阅读
- html - 如何使前置/代码标签包装占据容器的整个高度?
- wap - 在 Aruba 主 WAP 重新启动后,Aruba 虚拟控制器设置(例如国家代码和虚拟控制器 ip)不会保留
- python - 类型错误:+ 不支持的操作数类型:'Timedelta' 和 'datetime.time - python
- python - Pandas - 从值列表中删除行
- node.js - Firebase Auth:为什么在刷新令牌请求响应PERMISSION_DENIED一段时间后使用identitytoolkit signInWithCustomToken?
- visual-studio-code - 注释掉行时 vscode 保留缩进
- insert - MeekroDB - 使用“%s”占位符删除空格
- python - 使用范围的 Numpy MemoryError
- vtk - 如何使平滑的 vtk 网格顶点分布均匀?
- .net-core - 在运行时仍需要仅常量集我 dotnetcore