【问题标题】:avoiding exponential notation in JSON_EXTRACT function in BigQuery避免 BigQuery 中 JSON_EXTRACT 函数中的指数表示法
【发布时间】:2015-10-22 10:27:09
【问题描述】:

我正在使用 BigQuery 并将 JSON 字符串存储在某些字段中。 在这里,我有一个名为“json”的字段,其中包含如下 JSON 字符串:

{"log_id":939286972300751993,"status":"good"}

并使用下面的 sql 查询:

SELECT json, JSON_EXTRACT(json, "$.log_id") AS log_id
FROM dataset.table;

结果是:

                    json                         |       log_id
-------------------------------------------------+---------------------
{"log_id": 939286972300751993, "status": "good"} | 9.39286972300752e+17

但我期望的是:

                    json                         |       log_id
-------------------------------------------------+---------------------
{"log_id": 939286972300751993, "status": "good"} | 939286972300751993

"log_id" 在我的上下文中应该被视为 INTEGER。 有什么办法可以避免 JSON_EXTRACT 函数将大整数替换为指数符号?

【问题讨论】:

  • 据我所知,JSON 规范没有对数字范围施加任何限制,但大多数库确实有限制。如果您切换到字符串,您可能会更安全:{"log_id":"939286972300751993","status":"good"}
  • 感谢重播。是的,我认为你是对的。如果我可以重新定义架构,我会按照你说的做,但我已经拥有包含数据的庞大数据集,正如我所解释的,很难更新所有数据。
  • 你如何抛出你的查询?通过 GUI,通过 API?
  • 我尝试了 Web GUI 和 API,结果是一样的。

标签: sql json google-bigquery


【解决方案1】:

您可以在查询本身中将结果转换为 INTEGER。

SELECT json, INTEGER(JSON_EXTRACT(json, "$.log_id")) AS log_id
FROM dataset.table;

正如您问题的 cmets 中所述,在 JSON 中存储大量数字可能会导致您丢失任何超过 2^53 的数字的精度(在 http://rfc7159.net/rfc7159 中搜索“数字”)。如果发生这种情况,JSON 解析库本身就会丢失精度,因此在查询的其他地方强制转换为 INTEGER(或进行一些 API 级别的更改)将无济于事。

【讨论】:

  • 我明白这一点。谢谢你的详细解释。
【解决方案2】:

我同意 @jeremy-condit 和 @Álvaro-gonzález 关于存储大量数字的观点,但有时您无法更改所提供的数据。..

作为将JSON_EXTRACT 结果转换为整数导致空值的答案,我使用了regexp_extract

虽然不是最好的方法,但这可能对其他人有用:

SELECT json, integer(regexp_extract(json, "\"log_id\":([0-9]*),")) as log_id
FROM dataset.table;

【讨论】:

    猜你喜欢
    • 2016-06-20
    • 2019-02-06
    • 2014-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-20
    相关资源
    最近更新 更多