使用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)。
谢谢您的帮助!
罗伯特
答案 0 :(得分:1)
这里有几件事:
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}$')
答案 1 :(得分:0)
Google BigQuery's LIKE
operator不支持匹配的数字,也不在语法中使用[
字符(我也不认为ISO标准SQL可以-LIKE
远不及它强大正则表达式)。
X [NOT] LIKE Y
检查第一个操作数X中的
STRING
是否与第二个操作数Y
指定的模式匹配。表达式可以包含以下字符:
- 百分号“%”可以匹配任意数量的字符或字节
- 下划线“ _”匹配单个字符或字节
- 您可以使用两个反斜杠来转义“ \”,“ _”或“%”。例如, ”\%”。如果您使用原始字符串,则仅需一个反斜杠。例如,r“ \%”。
您应该改用REGEX_CONTAINS
。
我注意到,字符串格式测试不会告诉您日期是否有效。请考虑2019-02-31
具有有效的日期格式,但无效的日期值。我建议改为使用数据类型转换函数(将STRING
转换为DATE
值)。
答案 2 :(得分:0)
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