将时间戳记到四分之一小时

时间:2019-08-09 16:19:45

标签: sql google-bigquery

我有一张桌子,其中一列是时间戳。我想做的是一个SQL查询(兼容BigQuery),将每行的时间戳四舍五入到该时间之前的四分之一小时。 例子:

2019-07-05 21:11:28 UTC -> 2019-07-05 21:00:00 UTC 2019-07-05 21:17:05 UTC -> 2019-07-05 21:15:00 UTC 2019-07-05 20:29:56 UTC -> 2019-07-05 20:15:00 UTC 2019-07-05 21:55:39 UTC -> 2019-07-05 21:45:00 UTC

我发现TIMESTAMP_TRUNC可以四舍五入为分钟,但这将四舍五入为时间戳的分钟,而不是四分之一。

你们知道我该怎么做吗?

预先感谢

3 个答案:

答案 0 :(得分:0)

如果您对使用存储过程感到满意,可以执行以下操作:

declare @d datetime='2019-07-05 21:11:28'
select DATEADD(mi, DATEDIFF(mi, 0, @d)/15*15, 0)

之所以可行,是因为上面示例中的0整数实际上是纪元(1900-01-01)的开始。

答案 1 :(得分:0)

您可以使用和一些日期算法:

timestamp_trunc()

答案 2 :(得分:0)

以下是用于BigQuery标准SQL

#standardSQL
SELECT ts, 
  TIMESTAMP_SECONDS(UNIX_SECONDS(ts) - MOD(UNIX_SECONDS(ts), 15 * 60)) ts_rounded_to_quarter_of_hour
FROM `project.dataset.table`

另一个经过重构的版本是

#standardSQL
SELECT ts, 
  TIMESTAMP_SECONDS(ts_seconds_since_epoch - MOD(ts_seconds_since_epoch, 15 * 60)) ts_rounded_to_quarter_of_hour
FROM `project.dataset.table`, UNNEST([UNIX_SECONDS(ts)]) ts_seconds_since_epoch

最后,我最喜欢的版本是

#standardSQL
CREATE TEMP FUNCTION TIMESTAMP_TRUNC_TO_QUATER_OF_HOUR(ts TIMESTAMP) AS ((
  SELECT TIMESTAMP_SECONDS(ts_seconds_since_epoch - MOD(ts_seconds_since_epoch, 15 * 60))
  FROM UNNEST([UNIX_SECONDS(ts)]) ts_seconds_since_epoch
));
SELECT ts, 
  TIMESTAMP_TRUNC_TO_QUATER_OF_HOUR(ts) AS ts_rounded_to_quarter_of_hour
FROM `project.dataset.table` 

您可以使用问题中的示例数据来进行测试,如上示例所示

#standardSQL
CREATE TEMP FUNCTION TIMESTAMP_TRUNC_TO_QUATER_OF_HOUR(ts TIMESTAMP) AS ((
  SELECT TIMESTAMP_SECONDS(ts_seconds_since_epoch - MOD(ts_seconds_since_epoch, 15 * 60))
  FROM UNNEST([UNIX_SECONDS(ts)]) ts_seconds_since_epoch
));
WITH `project.dataset.table` AS (
  SELECT TIMESTAMP '2019-07-05 21:11:28 UTC' ts UNION ALL    --> 2019-07-05 21:00:00 UTC
  SELECT '2019-07-05 21:17:05 UTC' UNION ALL                 --> 2019-07-05 21:15:00 UTC
  SELECT '2019-07-05 20:29:56 UTC' UNION ALL                 --> 2019-07-05 20:15:00 UTC
  SELECT '2019-07-05 21:55:39 UTC'                           --> 2019-07-05 21:45:00 UTC
)
SELECT ts, 
  TIMESTAMP_TRUNC_TO_QUATER_OF_HOUR(ts) AS ts_rounded_to_quarter_of_hour
FROM `project.dataset.table`   

很明显,以上所有三个版本的返回结果均低于[相同]

Row     ts                      ts_rounded_to_quarter_of_hour    
1       2019-07-05 21:11:28     UTC 2019-07-05 21:00:00 UTC  
2       2019-07-05 21:17:05     UTC 2019-07-05 21:15:00 UTC  
3       2019-07-05 20:29:56     UTC 2019-07-05 20:15:00 UTC  
4       2019-07-05 21:55:39     UTC 2019-07-05 21:45:00 UTC