【问题标题】:Why is BigQuery converting some dates to timestamps but not others?为什么 BigQuery 将某些日期转换为时间戳,而不将其他日期转换为时间戳?
【发布时间】:2016-12-31 00:18:12
【问题描述】:

我们下面显示的 SQL 查询正在将字符串转换为时间戳字段,但在某些日期失败,而在其他日期没有失败。是什么导致此转换失败?

SELECT birthdate, TIMESTAMP(REGEXP_REPLACE(birthdate, r'(..)/(..)/(....)', r'\3-\2-\1')) ts
FROM [our_project:our_table] LIMIT 1000

这是结果。请注意,BigQuery 对许多日期都给出了“null”。为什么正则表达式失败?是否需要添加一些内容以使其更健壮?

这是我们尝试的第二个转化查询。

SELECT birthdate, TIMESTAMP(year + '-' + month + '-' + day) as output_timestamp
FROM (
  SELECT 
    birthdate, 
    REGEXP_EXTRACT(birthdate, '.*/([0-9]{4})$') as year, 
    REGEXP_EXTRACT(birthdate, '^([0-9]{2}).*') as day, 
    REGEXP_EXTRACT(birthdate, '.*/([0-9]{2})/.*') AS month 
  FROM 
    [our_project:our_table]
)
LIMIT 1000

请注意,这些结果中也出现了空值。

我们如何解决问题?

【问题讨论】:

    标签: sql timestamp google-bigquery


    【解决方案1】:

    如果您的数据具有时间戳的自定义格式,您始终可以在标准(非旧版)SQL - https://cloud.google.com/bigquery/sql-reference/functions-and-operators#parse_timestamp 中使用 PARSE_TIMESTAMP 函数 IE。以下所有查询

    select parse_timestamp("%Y-%d-%m", x) from
    unnest(["2016-31-12", "1999-01-02"]) x
    
    select parse_timestamp("%Y-%d-%m", x) from
    unnest(["2016-31-12", "1999-01-02"]) x
    
    select parse_timestamp("%Y-%b-%d", x) from
    unnest(["2016-Dec-31", "1999-Feb-01"]) x
    

    结果

    f0_  
    1   2016-12-31 00:00:00 UTC  
    2   1999-02-01 00:00:00 UTC 
    

    【讨论】:

      【解决方案2】:

      您没有使用受支持的TIMESTAMP 数据类型是否有原因?

      来自文档:

      您可以将 TIMESTAMP 数据类型描述为 UNIX 时间戳或日历日期时间。

      日期时间需要采用特定格式:

      格式为 YYYY-MM-DD HH:MM:SS 的日期和时间字符串。支持 UTC 和 Z 说明符。

      这还可以让您更轻松地查询此特定列,因为它可以让您利用 BigQuery 的标准 SQL 方言。 HOUR、DAYOFWEEK、DAYOFYEAR等命令

      下面是一个示例查询,它使用 BQ 的一个公共数据集使用时间戳字段查找最受欢迎的取件时间:

      SELECT
        HOUR(pickup_datetime) as pickup_hour, 
        COUNT(*) as pickup_count
      FROM
        [nyc-tlc:green.trips_2014]
      GROUP BY
        1
      ORDER BY 
        pickup_count DESC
      

      将产生:

      Row pickup_hour pickup_count     
      1   19  1059068  
      2   18  1051326  
      3   20  985664   
      4   17  957583   
      5   21  938378   
      6   22  908296   
      

      【讨论】:

      • 我们确实想使用 TIMESTAMP。问题的目的是我们试图将“STRING”类型的列转换为“TIMESTAMP”,但转换失败。我们采用上述方法修复了它。
      • 我明白了,我明白了。在加载到 BQ 之前将源数据格式化为有效的 TIMESTAMP 格式可能会更省力,而不是在列已经在 BQ 中时对其进行转换(如果您可以控制该过程)。
      【解决方案3】:

      事实证明,月份和日期被交换了(国际与美国)结果是时间戳的范围无效。一旦我们交换了日期和月份 - 然后转换就没有问题了。

      【讨论】:

      • 朋友不要让朋友在数据中使用美国日期格式!
      猜你喜欢
      • 2016-11-26
      • 1970-01-01
      • 1970-01-01
      • 2020-10-19
      • 2017-04-25
      • 2022-01-08
      相关资源
      最近更新 更多