将 JSON_EXTRACT 与 CAST 或 STR_TO_DATE 链接失败

Posted

技术标签:

【中文标题】将 JSON_EXTRACT 与 CAST 或 STR_TO_DATE 链接失败【英文标题】:Chaining JSON_EXTRACT with CAST or STR_TO_DATE fails 【发布时间】:2017-02-06 03:44:53 【问题描述】:

我正在尝试从 mysql 中的 JSONFIELD“数据”中提取日期时间。

但是,如果我执行简单的 JSON_EXTRACT,则返回字段类型是 JSON。

mysql> select JSON_EXTRACT(data, "$.new_time") from analytics limit 10;
+----------------------------------+
| JSON_EXTRACT(data, "$.new_time") |
+----------------------------------+
| NULL                             |
| "2016-09-30T04:00:00+00:00"      |
| "2016-09-29T05:30:00+00:00"      |
| NULL                             |
| "2016-10-01T05:30:00+00:00"      |
| "2016-09-27T23:00:00+00:00"      |
| NULL                             |
| "2016-09-23T01:30:00+00:00"      |
| "2016-09-23T04:00:00+00:00"      |
| "2016-09-27T01:30:00+00:00"      |
+----------------------------------+

我想将其转换为 MySQL DATETIME。但如果我链接 JSON_EXTRACT 和 STR_TO_DATETIME,我会得到所有 NULL 值:

mysql> select STR_TO_DATE(JSON_EXTRACT(data, "$.new_time") ,"%Y-%m-%d") from analytics_calendaranalytics limit 10;
+-----------------------------------------------------------+
| STR_TO_DATE(JSON_EXTRACT(data, "$.new_time") ,"%Y-%m-%d") |
+-----------------------------------------------------------+
| NULL                                                      |
| NULL                                                      |
| NULL                                                      |
| NULL                                                      |
| NULL                                                      |
| NULL                                                      |
| NULL                                                      |
| NULL                                                      |
| NULL                                                      |
| NULL                                                      |
+-----------------------------------------------------------+

同样,作为 DATETIME 的 CAST 也会失败:

mysql> select CAST(JSON_EXTRACT(data, "$.new_time") as DATETIME) from analytics_calendaranalytics limit 10;
+----------------------------------------------------+
| CAST(JSON_EXTRACT(data, "$.new_time") as DATETIME) |
+----------------------------------------------------+
| NULL                                               |
| NULL                                               |
| NULL                                               |
| NULL                                               |
| NULL                                               |
| NULL                                               |
| NULL                                               |
| NULL                                               |
| NULL                                               |
| NULL                                               |
+----------------------------------------------------+

当我从字符串值开始时,这两个命令都有效:

mysql> select CAST("2016-09-30T04:00:00+00:00" as DATETIME);
+-----------------------------------------------+
| CAST("2016-09-30T04:00:00+00:00" as DATETIME) |
+-----------------------------------------------+
| 2016-09-30 04:00:00                           |
+-----------------------------------------------+
1 row in set, 1 warning (0.00 sec)

mysql> select STR_TO_DATE("2016-09-30T04:00:00+00:00", "%Y-%m-%d");
+------------------------------------------------------+
| STR_TO_DATE("2016-09-30T04:00:00+00:00", "%Y-%m-%d") |
+------------------------------------------------------+
| 2016-09-30                                           |
+------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)

在解决此问题方面的任何帮助都将不胜感激!

【问题讨论】:

【参考方案1】:

你必须使用JSON_UNQUOTE

select CAST( JSON_UNQUOTE( JSON_EXTRACT(data, "$.new_time")) as DATETIME) from analytics_calendaranalytics limit 10;

会工作的。我说会因为你没有提供样本数据。我尝试如下:

select @js := JSON_OBJECT('new_time',"2016-09-30T04:00:00+00:00"  );

select CAST(JSON_UNQUOTE(JSON_EXTRACT(@js,'$.new_time')) as DATETIME);

以下查询也有效

 select STR_TO_DATE(JSON_UNQUOTE(JSON_EXTRACT(@js,'$.new_time')) ,"%Y-%m-%d");

【讨论】:

完美!谢谢@e4c5 很高兴能帮上忙 这也解决了我的问题,我只是尝试根据 json 字段更新表列,但它一直抛出 CAST 错误。如果您尝试输入 INT 字段,请确保取消引用。谢谢【参考方案2】:

更多READABLE方法是使用->>;

SELECT CAST(data->>'$.new_time' AS DATETIME) FROM analytics limit 10;

例子:

mysql> CREATE TABLE analytics (data json not null);
Query OK, 0 rows affected (0.03 sec)

mysql> INSERT INTO analytics (data) VALUES ('"new_time": "2021-04-21T04:00:00+00:00"');
Query OK, 1 row affected (0.01 sec)

mysql> SELECT CAST(data->>'$.new_time' AS DATETIME) FROM analytics limit 10;
+---------------------------------------+
| CAST(data->>'$.new_time' AS DATETIME) |
+---------------------------------------+
| 2021-04-21 04:00:00                   |
+---------------------------------------+
1 row in set, 1 warning (0.00 sec)

【讨论】:

以上是关于将 JSON_EXTRACT 与 CAST 或 STR_TO_DATE 链接失败的主要内容,如果未能解决你的问题,请参考以下文章

我想用 BigQuery 提取 Json 格式的数据。 UDF 或 json_extract

如何使用 JSON_EXTRACT 或 JSON_EXTRACT_SCALAR 在 Big Query 中读取多级 JSON 数据

Presto unnest json映射

将使用 JSON_EXTRACT 的查询从 MySQL 转换为 BigQuery

MySQL数据类型转换函数CAST与CONVERT的用法

当所述列的值为 NULL 时,我在可空列上使用 JSON_extract 函数的 where 语句得到确认?