【问题标题】:Grabbing a particular value from a json type in sql从 sql 中的 json 类型中获取特定值
【发布时间】:2021-07-08 17:04:28
【问题描述】:

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

[{'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'}]

【问题讨论】:

  • 在询问 SQL 问题时,请始终提供 DBMS(数据库和版本),例如作为标签。函数(用于 JSON)在很大程度上取决于您使用的数据库系统。
  • @hc_dev 刚刚修改为包含数据库
  • 我们要求您添加 minimal reproducible example 以显示您尝试的代码。我假设您是 SQLAmazon Redshift 的新手,所以我提供了一些快速入门的答案。但是,下次请在询问之前对文档进行研究!

标签: sql amazon-redshift


【解决方案1】:

研究数据库的 SQL 函数文档

请参阅Amazon Redshift SQL 的参考文档,了解JSON functions

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

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

  • 带有您的 JSON 内容(第一个参数)的 字段
  • JSN 路径作为字符串(第二个参数)

已应用

类似:

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

假定从给定数组的第一个元素(0,因为索引是从零开始!)为您提供列名称iSerial。如果该列包含以下 JSON in valid format,则结果应如预期:3 30J155001549

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

疑难解答:JSON 解析错误

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

查看类似内容:[XX000][500310] [Amazon](500310) Invalid operation: Parsed manifest is not a valid JSON object

您是否尝试过像官方文档的 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),您可以尝试使用带有合适文本的 UPDATE 语句或 String-functions 来更新值。

例子:

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

无效:单引号

[{
    'bus': '004'
}]

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

有效:双引号

[{
    "bus": "004"
}]

【讨论】:

  • @justanewb:您的 JSON 根本无效。请参阅我的更新答案。您应该确保输入/JSON 在插入数据库之前经过验证。否则,唯一的修复机制是使用带有 SQL replace-function 的 UPDATE 来更正所有无效的 JSON 值(用双引号替换单引号)。
  • 是的,您的权利无效,我没有插入它。这是我别人做的。我没有看到您的更新或已尝试过但仍然无法正常工作
  • @justanewb ...我的“更新”只是作为自助提示的解决方案...不是针对您的问题的复制粘贴就绪解决方案。注意:Stackoverflow 不是免费的编码服务?️
  • 剩下的就交给你了:?️ 在 Redshift 文档中搜索 char 或 CHR 函数来获取你想要替换的字符。 single-quote 或撇号的 ASCII 码编号为 39。这需要替换为 ASCII 码数字 34(双引号)
【解决方案2】:

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

select * from OPENJSON('你的 JSON 字符串')

【讨论】:

  • 是什么让你认为 SQL 函数 OPENJSON() 可以在给定的数据库上工作?借此机会提供基于同时给定 DBMS 的解决方案。
  • @hc_dev 实际上,当我发布答案时,没有在问题上指定 DBMS,并且我在屏幕上打开了 SQL Server SSMS。 (如果你真的想知道答案)。 :-)
  • @hc_dev 感谢您的积极响应。我会研究这个话题。通常我会通过一种常见的编程语言(C#、Python 等)在将 JSON 转换为 SQL 之前对其进行修复。
猜你喜欢
  • 2019-06-16
  • 1970-01-01
  • 2021-12-24
  • 2019-03-30
  • 2017-11-22
  • 2017-09-19
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多