BigQuery:验证所有日期的格式是否为 yyyy-mm-dd

Rob*_*anu 1 google-bigquery

使用 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'
Run Code Online (Sandbox Code Playgroud)

但结果是:“该查询没有返回结果。”

然后我使用以下代码检查 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'
Run Code Online (Sandbox Code Playgroud)

令人惊讶的是,它给出了birth_dat_col中的所有值,我已经验证了这些值并且具有正确的日期格式,但这个结果很可能是巧合。

非常奇怪(错误)的是,我使用的查询应该只产生错误格式的日期,但它实际上给了我正确的日期。关于这两个查询的一切似乎都是每个人角色的倒置。

此业务案例的任何查询的预期结果都是对所有格式不正确的日期进行计数(即使当前为 0)。

感谢您的帮助!

罗伯特

Ell*_*ard 5

这里有几件事:

  1. 如果您想了解如何使用LIKE 运算符,请阅读它的文档。看起来您正在尝试使用正则表达式语法,但 LIKE 运算符不将正则表达式作为输入。
  2. BigQuery 日期的标准格式是 YYYY-MM-DD,因此您可以尝试进行转换并查看结果是否是有效日期,例如:
SELECT SAFE_CAST(birth_day_col AS DATE) AS birth_day_col
FROM `project`.dataset.table
Run Code Online (Sandbox Code Playgroud)

对于任何格式不正确的值,这将返回 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
Run Code Online (Sandbox Code Playgroud)

此查询的结果将是所有不使用 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'
)
Run Code Online (Sandbox Code Playgroud)

如果要查找采用 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}$')
Run Code Online (Sandbox Code Playgroud)

例如:

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}$')
Run Code Online (Sandbox Code Playgroud)