【问题标题】:SQL : How to extract particular value from a key in data dictionarySQL:如何从数据字典中的键中提取特定值
【发布时间】:2022-01-27 20:37:06
【问题描述】:

我想使用 Oracle SQL 查询从以下给定数据结构中仅提取城市值。

例如:{"firstName":"Curtis","lastName":"C Fugatt","street1":"4146 Audiss Rd.","street2":null,"city":"Milton"}

PS:函数:json_value 不起作用,其他线程正在建议 Python 中的解决方案。我只想使用 SQL。

【问题讨论】:

  • 添加更多样本数据,并指定预期结果。
  • 这不是 JSON 数据结构是什么意思?您提供的示例是一个 JSON 对象,可以与 JSON_VALUE 一起使用:SELECT json_value ('{"firstName":"Curtis","lastName":"C Fugatt","street1":"4146 Audiss Rd.","street2":null,"city":"Milton"}','$.city') FROM DUAL;
  • 如果这不是json,那么请澄清一下什么是“数据字典”以及“下面的结构”代表什么。提取一些值的规则是什么?

标签: sql oracle data-dictionary


【解决方案1】:

如果您的值类似于 JSON(但不完全,因此您无法使用 JSON 函数对其进行解析),那么您可以使用以下方法解析类似 JSON 的键值对:

SELECT REGEXP_SUBSTR(
         value,
         '[,{]\s*"city"\s*:\s*"((\\[\/"bfnrt]|\\u[0-9a-fA-Z]{4}|[^\])*)"',
         1,
         1,
         NULL,
         1
       ) AS city
FROM   table_name

其中,对于样本数据:

CREATE TABLE table_name (value) AS
SELECT '{"firstName":"Curtis","lastName":"C Fugatt","street1":"4146 Audiss Rd.","street2":null,"city":"Milton"}' FROM DUAL UNION ALL
SELECT '{
  "not_this_one":
    "city",
  "big_city":
    "there",
  "little_city":
    "somewhere",
  "city":
      "here"
}' FROM DUAL;

注意:在第二个示例中,您不能天真地寻找city"city",因为它会匹配一个值而不是一个键。

输出:

CITY
Milton
here

但是,如果它是 JSON 数据(您的示例是),那么您可以(并且应该)使用 JSON 函数来解析它:

SELECT JSON_VALUE(value, '$.city') AS city
FROM   table_name;

db小提琴here

【讨论】:

  • SELECT JSON_VALUE(value, '$.city') AS city FROM table_name;这可能不起作用,因为 city 用双引号括起来。
  • @MishitaAgarwal 在 JSON 中,键和值必须用双引号括起来。它们在您的示例数据和我的答案中的示例数据中用双引号引起来(第一行是您的数据的复制/粘贴)。我的查询都适用于您的数据;如果您有无法正常工作的数据,请提供minimal reproducible example,因为我无法复制您在之前评论中所说的内容。
【解决方案2】:

对于您发布的示例数据,一个选项可能是:

SQL> with test (col) as
  2    (select '{"firstName":"Curtis","street2":null,"city":"Milton"}' from dual union all
  3     select '"lastName":"C Fugatt","street1":"4146 Audiss Rd.","city":"Los Angeles"}' from dual
  4    )
  5  select regexp_replace(substr(col, instr(col, 'city') + 7), '[^[:alnum:] ]', '') result
  6  from test;

RESULT
--------------------------------------------------------------------------------
Milton
Los Angeles

SQL>

它有什么作用?

  • substr 找到 city 字符串的第一个位置并在其上添加 7(以跳过 city 本身、双引号和冒号)并且 - 结果 - 将所有内容返回到字符串的末尾
    • 这意味着城市必须是字符串中的最后一个信息
  • regexp_replace 删除字母数字和空格以外的任何内容
  • 剩下的是城市名称(即最终结果)

当您改变主意时(因此city 不是字符串中的最后一个信息),一个选项可能是嵌套的SUBSTR

SQL> with test (col) as
  2    (select '{"firstName":"Curtis","street2":null,"city":"Milton"}' from dual union all
  3     select '"lastName":"C Fugatt","street1":"4146 Audiss Rd.","city":"Los Angeles"}' from dual union all
  4     select '"firstName":"Curtis","lastName":"C Fugatt","street1":"4146 Audiss Rd.","street2":null,"city":"Milton","state":"FL","zip":"32583","country":"USA","phone":"' from dual
  5    )
  6  select
  7    substr(substr(col, instr(col, 'city') + 7),                 -- everything that follows "city"
  8           1,                                                   -- starting from the 1st position
  9           instr(substr(col, instr(col, 'city') + 7), '"') - 1  -- up to the first double quote in that "everything that follows "city"" substring
 10          ) result
 11  from test;

RESULT
--------------------------------------------------------------------------------
Milton
Los Angeles
Milton

SQL>

【讨论】:

  • 感谢您的回答。但是,如果我们想要检索不是序列中最后一个键的值怎么办。如果假设示例变为: 地址:{"firstName":"Curtis","lastName":"C Fugatt","street1":"4146 Audiss Rd.","street2":null,"city":"Milton" ,"state":"FL","zip":"32583","country":"USA","phone":""} 然后上面的解决方案是让一切从 Miltonstate .....USAphone 开始。跨度>
  • 好吧,我们所知道的就是您告诉我们的。您从未说过 CITY 可能在其他地方,而是字符串中的最后一个信息。无论如何:我编辑了答案并添加了另一个示例;看看吧。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-19
  • 1970-01-01
  • 2018-08-30
  • 1970-01-01
  • 2023-01-24
  • 2021-02-08
相关资源
最近更新 更多