我在BigQuery(标准SQL)中具有以下代码:
SAFE_CAST (PARSE_DATE('%Y-%m-%d',JSON_EXTRACT_SCALAR(g.p_dataforanalytics,'$.birthday') ) as string)
此操作由于以下原因而失败:
解析函数的结果无效
问题是我无法控制在g.p_dataforanalytics
中获得的数据,其中有些是纯垃圾,格式不正确,有时甚至是不合理的值。
有没有一种方法可以定义如果PARSE_DATE()
失败,它将返回NULL并且不会抛出查询?
基本上我正在寻找任何编程语言中的try / catch之类的东西吗?
答案 0 :(得分:1)
在 parse 上使用SAFE.
前缀:
SAFE.PARSE_DATE('%Y-%m-%d', JSON_EXTRACT_SCALAR(g.p_dataforanalytics, '$.birthday') )
除非您需要这样的解决方案,否则我看不到将其转换回字符串的实用程序:
COALESCE(FORMAT('%Y-%m-%d',
COALESCE(SAFE.PARSE_DATE('%Y-%m-%d', JSON_EXTRACT_SCALAR(g.p_dataforanalytics, '$.birthday'),
SAFE.PARSE_DATE('%m/%d/%Y', JSON_EXTRACT_SCALAR(g.p_dataforanalytics, '$.birthday')
)
), JSON_EXTRACT_SCALAR(g.p_dataforanalytics, '$.birthday'
)
也就是说,如果代码对日期测试了不同的格式,请选择一种格式,然后将其转换回YYYY-MM-DD格式。而且,如果没有一种格式有效,则保留原始值。
答案 1 :(得分:0)
以下内容适用于BigQuery Standard SQL,并且(我认为)通过将moment.js库和BigQuery UDF与外部库一起使用,涵盖了大多数日期表示形式的疯狂变化。
注意:您需要将moment.js
上传到GCS上的your_bucket
#standardSQL
CREATE TEMPORARY FUNCTION PARSE_DATE_CUSTOM(format_string STRING, date_string STRING )
RETURNS STRING
LANGUAGE js AS """
return moment(date_string).format(format_string);
"""
OPTIONS (
library="gs://your_bucket/moment.js"
);
SELECT
JSON_EXTRACT_SCALAR(g.p_dataforanalytics, '$.birthday') birthday_in_json,
PARSE_DATE_CUSTOM('YYYY-MM-DD', JSON_EXTRACT_SCALAR(g.p_dataforanalytics, '$.birthday')) birthday
FROM `project.dataset.table` g
如您所见-这里引入了一个新的自定义函数PARSE_DATE_CUSTOM(format_string STRING, date_string STRING )
-可以接受表示最终输出所要使用的表示日期和格式的任何字符串。支持的格式为here
您可以像下面的简化示例一样使用虚拟数据进行测试,玩耍
#standardSQL
CREATE TEMPORARY FUNCTION PARSE_DATE_CUSTOM(format_string STRING, date_string STRING )
RETURNS STRING
LANGUAGE js AS """
return moment(date_string).format(format_string);
"""
OPTIONS (
library="gs://your_bucket/moment.js"
);
WITH `project.dataset.table` AS (
SELECT '{"birthday":"2000-12-31"}' p_dataforanalytics UNION ALL
SELECT '{"birthday":"2000-15-31"}' UNION ALL
SELECT '{"birthday":"12/31/2000"}' UNION ALL
SELECT '{"birthday":"31 Dec 2000"}' UNION ALL
SELECT '{"birthday":"Around 2000, Dec 31"}'
)
SELECT
JSON_EXTRACT_SCALAR(g.p_dataforanalytics, '$.birthday') birthday_in_json,
PARSE_DATE_CUSTOM('YYYY-MM-DD', JSON_EXTRACT_SCALAR(g.p_dataforanalytics, '$.birthday')) birthday
FROM `project.dataset.table` g
有结果
Row birthday_in_json birthday
1 2000-12-31 2000-12-31
2 2000-15-31 Invalid date
3 12/31/2000 2000-12-31
4 31 Dec 2000 2000-12-31
5 Around 2000, Dec 31 2000-12-31