从 json 类型中获取特定值 sql

Grabbing a particular value from a json type in sql

我在一个列中有这些不同的条目,看起来像这样

[{'bus': '008', 'device': '002', 'bDeviceClass': '0 (Defined at Interface level)',  'iSerial': '3 30J155001549',... }]

我想获取 iSerial30J155001549,但我不确定如何在 sql 中执行此操作。非常感谢任何建议。我们使用的数据库是Redshift。

我试过了

SELECT json_extract_path_text(
    json_extract_array_element_text(device_usb,0), 'iSerial'
)
FROM table
LIMIT 1;

但是我收到这个错误

[XX000][500310] [Amazon](500310) Invalid operation: JSON parsing error Details: ----------------------------------------------- error: JSON parsing er ...

这是一个完整的例子

[{'bus': '004', 'device': '002', 'bDeviceClass': '0 (Defined at Interface level)', 'bInterfaceClass': '3 Human Interface Device', 'bInterfaceProtocol': '2 Mouse', 'idVendor': '0x413c Dell Computer Corp.', 'idProduct': '0x301a', 'iManufacturer': '1 PixArt', 'iProduct': '2 Dell MS116 USB Optical Mouse', 'iSerial': '0', 'MaxPower': '100mA'}, {'bus': '003', 'device': '014', 'bDeviceClass': '224 Wireless', 'bInterfaceClass': '224 Wireless', 'bInterfaceProtocol': '1 Bluetooth', 'idVendor': '0x8087 Intel Corp.', 'idProduct': '0x07dc', 'iManufacturer': '0', 'iProduct': '0', 'iSerial': '0', 'MaxPower': '100mA'}, {'bus': '003', 'device': '010', 'bDeviceClass': '0 (Defined at Interface level)', 'bInterfaceClass': '3 Human Interface Device', 'bInterfaceProtocol': '0 None', 'idVendor': '0x413c Dell Computer Corp.', 'idProduct': '0x2113', 'iManufacturer': '0', 'iProduct': '2 Dell KB216 Wired Keyboard', 'iSerial': '0', 'MaxPower': '100mA'}, {'bus': '005', 'device': '002', 'bDeviceClass': '0 (Defined at Interface level)', 'bInterfaceClass': '3 Human Interface Device', 'bInterfaceProtocol': '0 None', 'idVendor': '0x0c2e Metro', 'idProduct': '0x09cf', 'iManufacturer': '1 Honeywell Imaging & Mobility', 'iProduct': '2 CCB02', 'iSerial': '8 16197B4974', 'MaxPower': '500mA'}]

您可以通过以下方式提取 JSON:

select * 来自 OPENJSON('your JSON string')

研究 SQL 函数的数据库文档

参见 Amazon Redshift SQL 关于 JSON functions:

的参考文档

json_extract_path_text('json_string', 'path_elem' [,'path_elem'[, …] ] [, null_if_invalid ] )

此函数可用于将字段提取为文本。你有两个 pass 2 参数:

  • 字段 与您的 JSON-content(第一个参数)
  • 作为字符串的 JSN 路径(第二个参数)

已应用

类似于:

SELECT
json_extract_path_text(
    json_extract_array_element_text(jsonContainingField,0), 'iSerial'
)
FROM table

假设从给定的 array 的第一个元素(0 因为索引是从零开始的!)给你列名 iSerial .如果该列包含以下 JSON 的有效格式 ,则结果应符合预期:3 30J155001549

[
  {
    'bus': '008', 
    'device': '002', 
    'bDeviceClass': '0 (Defined at Interface level)',
    'iSerial': '3 30J155001549'
   }
]

疑难解答:JSON 解析错误

您收到的错误消息似乎表明传递给函数(或列的内容)的 JSON 无效 JSON。

查看类似内容:

您是否像官方文档的 JSON-函数示例中那样,通过将常量 JSON-字符串传递给函数来尝试干式 运行?

据我所知,有效的 JSON 需要将字段和文本值括在 双引号 中,例如 "fieldName": "textValue" 而不是 'fieldName': 'textValue'.

先验证 JSON

您可以在计算机上使用一些免费工具在网络上检查每个 JSON。例如 JsonLint.com 将给定的 JSON 报告为 invalid!

在 Redshift

中验证 JSON

使用IS_VALID_JSON函数检查哪些行包含无效的JSON,如SELECT device_usb, IS_VALID_JSON(device_usb) FROM table.

对于每个无效结果(其中返回 false),您可以尝试使用带有合适文本或 String-functions.

的 UPDATE 语句来更新该值

示例:

UPDATE table SET device_usb = TRANSLATE(device_usb, ''', '"') WHERE IS_VALID_JSON(device_usb) = 'false'

无效:单引号

[{
    'bus': '004'
}]

将所有单引号 ' 稍微替换为必需的双引号 " 使其有效。

有效:双引号

[{
    "bus": "004"
}]