如何在BigQuery、H2、Hadoop、PrestoSQL等数据库查询季度起止时间
需求为传入任意带时间戳的日期值,返回对应季度首日(时间为00:00:00)与季度末日(时间为23:59:59),以下是不同数据库的具体实现,示例默认以传入当前时间戳为演示,将代码中的当前时间函数替换为目标时间字段/入参即可适配任意输入场景。
各数据库实现
Couchbase(N1QL)
实现代码:SELECT DATE_TRUNC_STR(NOW(), 'quarter') AS quarter_start, DATE_ADD_STR(DATE_TRUNC_STR(DATE_ADD_STR(NOW(), 3, 'month'), 'quarter'), -1, 'second') AS quarter_end逻辑说明:先按季度粒度截断时间得到季度首日0点,将时间往后推3个月截断到下一季度首日,减去1秒即为当前季度最后时刻。
BigQuery
实现代码:SELECT TIMESTAMP_TRUNC(CURRENT_TIMESTAMP(), QUARTER) AS quarter_start, TIMESTAMP_SUB( TIMESTAMP_ADD(TIMESTAMP_TRUNC(CURRENT_TIMESTAMP(), QUARTER), INTERVAL 3 MONTH), INTERVAL 1 SECOND ) AS quarter_end逻辑说明:使用
TIMESTAMP_TRUNC函数指定QUARTER粒度直接获取季度起始时间,往后偏移3个月到下一季度起点,减1秒得到季度结束时间。H2数据库
实现代码:SELECT DATEADD(QUARTER, DATEDIFF(QUARTER, DATE '1900-01-01', CURRENT_TIMESTAMP), DATE '1900-01-01') AS quarter_start, DATEADD(SECOND, -1, DATEADD(QUARTER, DATEDIFF(QUARTER, DATE '1900-01-01', CURRENT_TIMESTAMP) + 1, DATE '1900-01-01')) AS quarter_end逻辑说明:通过固定基准日期计算输入时间与基准日的季度差值,将差值累加回基准日得到季度起始点,再偏移1个季度后减1秒得到季度终点。
Hadoop生态(Hive/Spark SQL)
实现代码:SELECT CAST(trunc(current_timestamp(), 'Q') AS TIMESTAMP) AS quarter_start, CAST( concat( date_sub(add_months(trunc(current_timestamp(), 'Q'), 3), 1), ' 23:59:59' ) AS TIMESTAMP ) AS quarter_end逻辑说明:
trunc函数传入Q参数可直接返回季度首日的日期值,转为时间戳后默认时间为00:00:00;将季度首日往后加3个月再减1天得到季度最后一天的日期,拼接23:59:59后转为时间戳即为季度结束时间。PrestoSQL/Trino
实现代码:SELECT date_trunc('quarter', CURRENT_TIMESTAMP) AS quarter_start, date_trunc('quarter', CURRENT_TIMESTAMP) + INTERVAL '3' MONTH - INTERVAL '1' SECOND AS quarter_end逻辑说明:遵循标准SQL的
date_trunc逻辑,截断到季度粒度获取起始时间,加3个月减1秒得到季度结束时间。
通用逻辑说明:所有实现核心思路一致,即先定位输入时间所在季度的首日0点,再偏移3个月到下一季度起点,减去1秒得到当前季度的最后时刻,无需额外判断每个季度的具体天数,适配所有闰年、大小月场景。
内容的提问来源于stack exchange,提问作者user18781702

