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

Google bigquery BigQuery:验证所有日期的格式是否为yyyy-mm-dd,google-bigquery,Google Bigquery,使用Google BIGQUERY,我需要检查名为birth\u day\u col的列中的值是否正确且符合所需的日期格式:YYYY-MM-DD。此列中的值定义为字符串。此列中的值当前的格式如下:YYYY-MM-DD 我在互联网上做了很多研究,发现了一个有趣的解决方法。以下查询: SELECT DISTINCT birth_day_col FROM `project.dataset.datatable` WHERE birth_day_col LIKE '[1-2][0-

使用Google BIGQUERY,我需要检查名为birth\u day\u col的列中的值是否正确且符合所需的日期格式:YYYY-MM-DD。此列中的值定义为字符串。此列中的值当前的格式如下: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'
令人惊讶的是,它给出了出生日期中的所有值,我已经验证了这些值,并且是正确的日期格式,但是这个结果很可能是巧合

非常奇怪(错误)的是,我使用了一个只会产生错误格式日期的查询,但它实际上给出了正确的日期。关于这两个问题的一切似乎都是各自角色的颠倒

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

谢谢你的帮助

Robert

不支持匹配数字,也不在语法中使用
[
字符(我认为ISO标准SQL也不支持-
,比如
远没有Regex强大)

X[不]像Y

检查第一个操作数X中的
字符串
是否与第二个操作数
Y
指定的模式匹配。表达式可以包含以下字符:

  • 百分号“%”匹配任意数量的字符或字节
  • 下划线“\”与单个字符或字节匹配
  • 可以使用两个反斜杠转义“\”、“\%”或“%”。例如,“\%”。如果使用原始字符串,则只需要一个反斜杠。例如,r“\%”
您应该改用
REGEX\u CONTAINS

我注意到,字符串格式测试不会告诉您日期是否有效,但是,请考虑<代码> 2019-02-31/<代码>具有有效的日期格式,但无效日期值。建议使用数据类型转换函数(将<代码>字符串< /代码>转换为<代码>日期<代码>值)相反。

不支持匹配数字,也不在语法中使用
[
字符(我认为ISO标准SQL也不支持-
,比如
远没有Regex强大)

X[不]像Y

检查第一个操作数X中的
字符串
是否与第二个操作数
Y
指定的模式匹配。表达式可以包含以下字符:

  • 百分号“%”匹配任意数量的字符或字节
  • 下划线“\”与单个字符或字节匹配
  • 可以使用两个反斜杠转义“\”、“\%”或“%”。例如,“\%”。如果使用原始字符串,则只需要一个反斜杠。例如,r“\%”
您应该改用
REGEX\u CONTAINS


我注意到,字符串格式测试不会告诉您日期是否有效,但是,请考虑<代码> 2019-02-31/<代码>有一个有效的日期格式,但有一个无效的日期值。我建议使用一个数据类型转换函数(将<代码>字符串>代码>转换成<代码>日期>代码>值。

  • 如果您想了解如何使用它,请阅读文档。看起来您正在尝试使用正则表达式语法,但like运算符不将正则表达式作为输入
  • BigQuery日期的标准格式为YYYY-MM-DD,因此您可以尝试强制转换,查看结果是否为有效日期,例如:
  • 这将为任何格式不正确的值返回null。如果要查找所有格式不正确的值,可以在筛选器中使用
    SAFE\u 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\u 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}$')
    

    这里有几件事:

  • 如果您想了解如何使用它,请阅读文档。看起来您正在尝试使用正则表达式语法,但like运算符不将正则表达式作为输入
  • BigQuery日期的标准格式为YYYY-MM-DD,因此您可以尝试强制转换,查看结果是否为有效日期,例如:
  • 这将为任何格式不正确的值返回null。如果要查找所有格式不正确的值,可以在筛选器中使用
    SAFE\u 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\u 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}$')
    

    BigQuery标准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   
    

    BigQuery标准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   
    

    您的查询使用正斜杠
    /
    而不是破折号
    -
    作为日期组件分隔符。ISO 8601使用破折号,而不是斜杠。感谢您的反馈。我没有提到它。我认为它不相关。我已经尝试使用
    -
    的instad,但我得到了相同的结果。使用
    时也是如此e> 而是
    /
    。当我使用