是否可以通过在 Netezza 中使用 select 语句来解析 json?

问题描述

我的表的一列中有 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)

您也可以参考https://www.ibm.com/support/knowledgecenter/SSTNZ3/com.ibm.ips.doc/postgresql/dbuser/r_dbuser_functions_expressions.html了解更多详情。

看看你上面的评论,就像

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
....

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...