我正在尝试将 Oracle 12c 查询迁移到 Postgres11.5。
这是 json:
{
"cost": [{
"spent": [{
"ID": "HR",
"spentamount": {
"amount": 2000.0,
"country": "US"
}
}]
}],
"time": [{
"spent": [{
"ID": "HR",
"spentamount": {
"amount": 308.91,
"country": "US"
}
}]
}]
}
以下是必须迁移到 Postgres 11.5 的查询:
select js.*
from P_P_J r,
json_table(r.P_D_J, '$.*[*]'
COLUMNS(NESTED PATH '$.spent[*]'
COLUMNS(
ID VARCHAR2(100 CHAR) PATH '$.ID',
amount NUMBER(10,4) PATH '$.spentamount.amount',
country VARCHAR2(100 CHAR) PATH '$.spentamount.country'))
) js
结果:
ID, amount, country
HR, 2000.0,US
HR,308.91,US
我有两个问题:
$.*[*]
是什么意思?我们如何在 Postgres 中迁移此查询,以便它直接查看“花费”,而不是导航“成本”->“花费”或“时间”->“花费”
最佳答案
Postgres 中没有直接替代 json_table 的方法。您必须组合多个调用才能分解 JSON 结构。
您没有向我们展示您的预期输出,但据我所知,以下内容应该具有相同的效果:
select e.item ->> 'ID' as id,
(e.item #>> '{spentamount, amount}')::numeric as amount,
e.item #>> '{spentamount, country}' as country
from p_p_j r
cross join jsonb_each(r.p_d_j) as a(key, val)
cross join lateral (
select *
from jsonb_array_elements(a.val)
where jsonb_typeof(a.val) = 'array'
) as s(element)
cross join jsonb_array_elements(s.element -> 'spent') as e(item)
;
JSON 路径表达式 '$.*[*]
的意思是:迭代所有顶级键,然后迭代其中找到的所有数组元素以及嵌套路径 '$.花费[*]'
然后再次迭代其中的所有数组元素。这些步骤反射(reflect)在到达那里所需的三个 JSON 函数调用中。
使用 Postgres 12,这会更容易一些,因为这可以通过对 jsonb_path_query()
的一次调用来完成,它也使用 JSON 路径来使用非常相似的 JSON 路径表达式来访问元素:
select e.item ->> 'ID' as id,
(e.item #>> '{spentamount, amount}')::numeric as amount,
e.item #>> '{spentamount, country}' as country
from p_p_j r
cross join jsonb_path_query(r.p_d_j, '$.*[*].spent[*]') as e(item)
;
关于json - Oracle JSON_TABLE 到 PostgreSQL - 如何从 JSON 列中的第二个分层键进行搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61731987/