问题描述
我的表的一列中有 json 数据,我想通过在 Netezza 中使用 select 语句来解析 json 数据。我无法弄清楚。 大家能帮我解决这个问题吗? 假设我有 TableA 并且这个表有列 Customer_detail。 customer_detail 字段中的数据如下所示
'{"Customer":[{"id":"1","name":"mike","address":"NYC"}]}'
现在我想从 customer_detail 列的客户对象中查询 id。
提前致谢。
解决方法
从 NPS 11.1.0.0 开始,您可以在 NPS 中解析和使用 json 数据类型本身。
这是一个例子
SYSTEM.ADMIN(ADMIN)=> create table jtest(c1 jsonb);
CREATE TABLE
SYSTEM.ADMIN(ADMIN)=> insert into jtest values('{"name": "Joe Smith","age": 28,"sports": ["football","volleyball","soccer"]}');
INSERT 0 1
SYSTEM.ADMIN(ADMIN)=> insert into jtest values('{"name": "Jane Smith","age": 38,"sports": ["volleyball","soccer"]}');
INSERT 0 1
SYSTEM.ADMIN(ADMIN)=> select * from jtest;
C1
----------------------------------------------------------------------------------
{"age": 28,"name": "Joe Smith","soccer"]}
{"age": 38,"name": "Jane Smith","soccer"]}
(2 rows)
SYSTEM.ADMIN(ADMIN)=> select c1 -> 'name' from jtest where c1 -> 'age' > 20::jsonb ;
?COLUMN?
--------------
"Joe Smith"
"Jane Smith"
(2 rows)
看看你上面的评论,就像
select customer_detail::json -> 'Customer' -> 0 -> 'id' as id,customer_detail::json -> 'Customer' -> 0 -> 'name' as name
from ...
这将在每次执行期间将文本解析为 json。性能更高的方法是将 customer_detail
转换为 jsonb
数据类型
如果 NPS 版本低于 11.1.x,则 json 处理需要在 (a) 外部完成,如使用 sql 获取 json 数据,然后在数据库外部处理它或 (b) 使用 UDF - 创建 UDF支持json解析
例如 -
使用选择的编程语言,处理 SQL 外部的 json
import nzpy # install using "python3 -m pip install nzpy"
import os
import json
# assume NZ_USER,NZ_PASSWORD,NZ_DATABASE and NZ_HOST are set
con = nzpy.connect(user=os.environ["NZ_USER"],password=os.environ["NZ_PASSWORD"],host=os.environ["NZ_HOST"],database=os.environ["NZ_DATABASE"],port=5480)
with con.cursor() as cur:
cur.execute('select customer_detail from ...')
for customer_detail in cur.fetch_all():
c = json.loads(customer_detail)
print((c['Customer'][0]['name'],c['Customer'][0]['id']))
或者创建一个解析 json 的 UDF 并在 SQL 查询中使用它
如果这些都不是选项,并且 json 总是格式良好(即没有新行,只有一个名为“id”的键和一个名为“name”的键等),那么正则表达式可能是一种解决方法,虽然不推荐,因为它不是真正的 json 解析器
select regexp_extract(customer_detail,'"id"[[:space:]]*:[[:space:]]*"([^"]+)"',1,1) as id,regexp_extract(customer_detail,'"name"[[:space:]]*:[[:space:]]*"([^"]+)"',1) as name
....