BigQuery 日期和时间函数在时间戳列上返回 NULL

Posted

技术标签:

【中文标题】BigQuery 日期和时间函数在时间戳列上返回 NULL【英文标题】:BigQuery Date and Time Functions returning NULL on a timestamp column 【发布时间】:2015-09-09 06:51:58 【问题描述】:

我正在使用 LAG() 和 LEAD() 从表中的一个时间戳列中提取 3 个时间戳列:timestamp、prev_timestamp、next_timestamp。我需要做一些简单的日期和时间格式化,但是当我在 prev_timestamp 或 next_timestamp 上使用 MONTH() 之类的函数时,它会返回 NULL。

结果列的架构类型是正确的 (TIMESTAMP),并且由于某种原因,常规时间戳日期和时间格式有效。如何使它正确返回所有 3 列的月份?

示例代码为时间戳列返回月份,为上一个和下一个时间戳列返回 NULL:

SELECT 
  MONTH(timestamp) AS month,
  MONTH(prev_timestamp) AS prev_month,
  MONTH(next_timestamp) AS next_month
FROM (
  SELECT
    timestamp,
    LAG(timestamp,1) OVER (PARTITION BY id ORDER BY timestamp) prev_timestamp,
    LEAD(timestamp,1) OVER (PARTITION BY id ORDER BY timestamp) next_timestamp
  FROM timestamp_table
  )

【问题讨论】:

【参考方案1】:

所以在测试和检查了几件事后,我实际上从Mikhail's answer 中得到启发,并意识到他的答案是不正确的,因为滞后/领先不会返回毫秒,而是微秒(为什么?这是任何人的猜测)。

SELECT 
  MONTH(timestamp) AS month,
  MONTH(MSEC_TO_TIMESTAMP((prev_timestamp/1000))) AS prev_month,
  MONTH(MSEC_TO_TIMESTAMP((next_timestamp/1000))) AS next_month
FROM (
  SELECT
    timestamp,
    LAG(timestamp,1) OVER (PARTITION BY id ORDER BY timestamp) prev_timestamp,
    LEAD(timestamp,1) OVER (PARTITION BY id ORDER BY timestamp) next_timestamp
  FROM timestamp_table
  )

应该可以。我刚刚测试了创建一个包含三行时间戳的表。在没有 /1000 的情况下使用它,我的滞后/领先版本给出了不同的月份。我测试过,如果你不做除法,你最终会在第 47 个千年的某个地方结束。

【讨论】:

这看起来很有效 - 我仍然很好奇为什么它有效。我对导致我们必须从 MSEC 进行转换的类型转换有什么不明白的地方,这是什么时候发生的? @AaronR 我不完全确定原因,但我认为在内部,为了节省空间,时间戳被保存为“自纪元以来的微秒”。 “Lead”和“Lag”函数可能会返回“无格式”,迫使我们使用该解决方法【参考方案2】:

试试下面

SELECT 
  MONTH(MSEC_TO_TIMESTAMP(timestamp)) AS month,
  MONTH(MSEC_TO_TIMESTAMP(prev_timestamp)) AS prev_month,
  MONTH(MSEC_TO_TIMESTAMP(next_timestamp)) AS next_month
FROM (
  SELECT
    timestamp,
    LAG(timestamp,1) OVER (PARTITION BY id ORDER BY timestamp) prev_timestamp,
    LEAD(timestamp,1) OVER (PARTITION BY id ORDER BY timestamp) next_timestamp
  FROM timestamp_table
  )

【讨论】:

用时间戳尝试这个(我做了一个“选择CURRENT_TIMESTAMP()”作为我的测试表)给出了一个类型错误......不确定这是这里的解决方案。明白了,算了。第一个时间戳不需要 MSEC,因为它确实返回了一个时间戳。这是其他需要改变的人

以上是关于BigQuery 日期和时间函数在时间戳列上返回 NULL的主要内容,如果未能解决你的问题,请参考以下文章

在时间戳列上为使用年份函数的查询创建索引

使用 Pandas query() 过滤时间戳列上的数据帧

使用特定时间戳列将 CSV 导入 BigQuery 上的分区表?

在谷歌表单时间戳列上查询“今天”?

Bigquery (Standard Sql) - 年月日期格式

Bigquery:如何将 2 个时间戳列合并为 1 个列?