BigQuery:验证所有日期的格式为 yyyy-mm-dd
Posted
技术标签:
【中文标题】BigQuery:验证所有日期的格式为 yyyy-mm-dd【英文标题】:BigQuery: Validate that all dates are formatted as yyyy-mm-dd 【发布时间】:2019-05-10 13:35:02 【问题描述】:使用 Google BIGQUERY,我需要检查名为birth_day_col 的列中的值是否是正确且所需的日期格式:YYYY-MM-DD。此列中的值定义为 STRING。此外,此列中的值目前采用以下格式:YYYY-MM-DD。
我在互联网上进行了大量研究,发现了一个有趣的解决方法。以下查询:
SELECT
DISTINCT birth_day_col
FROM `project.dataset.datatable`
WHERE birth_day_col LIKE '[1-2][0-9][0-9][0-9]/[0-1][0-9]/[0-3][0-9]'
AND country_code = 'country1'
但结果是:“此查询未返回任何结果。”
然后我使用以下代码检查了 NOT:
SELECT
DISTINCT birth_day_col
FROM `project.dataset.datatable`
WHERE NOT(birth_day_col LIKE '[1-2][0-9][0-9][0-9]/[0-1][0-9]/[0-3][0-9]')
AND country_code = 'country1'
令人惊讶的是,它给出了birth_dat_col 中的所有值,我已经验证并且日期格式正确,但这个结果很可能是巧合。
很奇怪(错误),我使用的查询应该只导致错误的日期格式,但它实际上给了我正确的日期。这两个查询的所有内容似乎都在颠倒每个人的角色。
对此业务案例的任何查询的预期结果是计算所有格式不正确的日期(即使当前为 0)。
感谢您的帮助!
罗伯特
【问题讨论】:
您的查询使用正斜杠/
而不是破折号 -
作为日期组件分隔符。 ISO 8601 使用破折号,而不是斜线。
感谢您的反馈。我没有提到它。认为这无关紧要。我已经尝试使用-
instad of /
,但我得到了相同的结果。使用 .
而不是 /
时相同。
你试过用REGEX_CONTAINS
代替LIKE
吗?
当我使用NOT
函数时,它看起来几乎完全绕过了LIKE
函数,而是执行标准SELECT
,只检查WHERE country_code = 'country1'
。
【参考方案1】:
这里有几件事:
-
如果您想了解如何使用它,请阅读the LIKE operator 的文档。您似乎正在尝试使用正则表达式语法,但 LIKE 运算符不将正则表达式作为输入。
BigQuery 日期的标准格式是 YYYY-MM-DD,因此您可以尝试强制转换并查看结果是否为有效日期,例如:
SELECT SAFE_CAST(birth_day_col AS DATE) AS birth_day_col
FROM `project`.dataset.table
这将为任何格式不正确的值返回 null。如果你想找到所有格式不正确的,你可以在过滤器中使用SAFE_CAST
:
SELECT DISTINCT birth_day_col AS invalid_date
FROM `project`.dataset.table
WHERE SAFE_CAST(birth_day_col AS DATE) IS NULL
此查询的结果将是所有不使用 YYYY-MM-DD 格式的日期字符串。如果你想检查斜线,你可以使用REGEXP_CONTAINS
,例如试试这个:
SELECT
date,
REGEXP_CONTAINS(date, r'^[0-9]4/[0-9]2/[0-9]2$')
FROM (
SELECT '2019/05/10' AS date UNION ALL
SELECT '2019-05-10' UNION ALL
SELECT '05/10/2019'
)
如果您想查找 YYYY-MM-DD 格式或 YYYY/MM/DD 格式的所有日期,您可以使用如下查询:
SELECT
DISTINCT date
FROM `project`.dataset.table
WHERE REGEXP_CONTAINS(date, r'^[0-9]4[/\-][0-9]2[/\-][0-9]2$')
例如:
SELECT
DISTINCT date
FROM (
SELECT '2019/05/10' AS date UNION ALL
SELECT '2019-05-10' UNION ALL
SELECT '05/10/2019'
)
WHERE REGEXP_CONTAINS(date, r'^[0-9]4[/\-][0-9]2[/\-][0-9]2$')
【讨论】:
是的,我在网上找到了 SAFE_CAST 的参考资料。我只是不明白使用它是否会给我 100% 正确的结果。 SAFE_CAST ... AS DATE 是否也会检查日期是否正确?例如,正如@Dai 下面所说:如果你有 2019/02/30 怎么办?如果这也检查这个会很有趣。请指教。谢谢! :)CAST
和 SAFE_CAST
要求字符串的格式为 YYYY-MM-DD。它不能有斜线。我添加了另一个示例...目前还不清楚您想要做什么,但希望这很有用。【参考方案2】:
BigQuery Standrad SQL 的另一个示例 - 使用 SAFE.PARSE_DATE
#standardSQL
WITH `project.dataset.table` AS (
SELECT '1980/08/10' AS birth_day_col UNION ALL
SELECT '1980-08-10' UNION ALL
SELECT '08/10/1980'
)
SELECT birth_day_col
FROM `project.dataset.table`
WHERE SAFE.PARSE_DATE('%Y-%m-%d', birth_day_col) IS NULL
所有日期列表的结果不是格式为 yyyy-mm-dd
Row birth_day_col
1 1980/08/10
2 08/10/1980
【讨论】:
【参考方案3】:Google BigQuery's LIKE
operator 不支持匹配数字,也不在其语法中使用 [
字符(我认为 ISO 标准 SQL 也不支持 - LIKE
远没有 Regex 强大)。
X [NOT] LIKE Y
检查第一个操作数 X 中的
百分号“%”匹配任意数量的字符或字节 下划线“_”匹配单个字符或字节 您可以使用两个反斜杠转义“\”、“_”或“%”。例如, ”\%”。如果您使用的是原始字符串,则只需要一个反斜杠。例如,r"\%"。STRING
是否与第二个操作数Y
指定的模式匹配。表达式可以包含以下字符:
您应该改用REGEX_CONTAINS
。
我注意到,字符串格式测试不会告诉您日期是否有效。考虑2019-02-31
的日期格式有效,但日期值无效。我建议改用数据类型转换函数(将STRING
转换为DATE
值)。
【讨论】:
以上是关于BigQuery:验证所有日期的格式为 yyyy-mm-dd的主要内容,如果未能解决你的问题,请参考以下文章
将字符串转换为BIGQUERY中的日期当日期格式如下时:M / D / YYYY