我试图搜索,但找不到任何东西。但我正在使用 postgresql,但我想每 6 小时进行一次分组。所以类似于
date_trunc('hour', start_date)
但每 6 小时一次。
一种方法是使用日期和时间:
select date_trunc('day', start_date) + floor(extract(hour from start_date) / 6.0) * 6 * interval '1 hour' as yyyymmddhh6,
count(*)
from t
group by yyyymmddhh6;
这里是一个db<>小提琴。
我建议使用this通用函数。
create or replace function interval_date_trunc
(trunc_period interval, ts timestamptz, base_ts timestamptz default '1970-01-01Z')
returns timestamptz language sql immutable as
$fn$
select
base_ts
+ floor(extract(epoch from ts - base_ts) / extract(epoch from trunc_period))::bigint
* trunc_period;
$fn$;
然后
select interval_date_trunc(interval '6 hours', start_date) as running_6h,
count(*)
from t
group by running_6h;
该函数也可用于其他运行间隔聚合的情况。
添加新答案,因为我认为这种方法更适合您的需求。总之,我们将小时范围连接到 start_date 的日期部分,以便当您向用户显示聚合数据时不会让他们感到困惑
with cte (start_date) as
(select '2020-01-09 05:32:43' union all
select '2020-01-09 17:32:43' union all
select '2020-01-09 22:32:43' union all
select '2020-01-09 21:32:43' union all
select '2020-01-09 11:32:43')
select start_date,
left(start_date,10) ||
to_char(floor(extract(hour from start_date::timestamp)/6)*6,'00h -') ||
to_char(ceil(extract(hour from start_date::timestamp)/6)*6,'00h') as start_date_group
from cte
输出
+---------------------+----------------------+
| start_date | start_date_group |
+---------------------+----------------------+
| 2020-01-09 05:32:43 | 2020-01-09 00h - 06h |
| 2020-01-09 17:32:43 | 2020-01-09 12h - 18h |
| 2020-01-09 22:32:43 | 2020-01-09 18h - 24h |
| 2020-01-09 21:32:43 | 2020-01-09 18h - 24h |
| 2020-01-09 11:32:43 | 2020-01-09 06h - 12h |
+---------------------+----------------------+
从PG 14开始,就可以使用
date_bin
:
-- Params: interval, datetime, source
SELECT date_bin('6 hours', start_date, date_trunc('day',start_date))
实际来源确保在 00、06、12、18 小时对齐。
文档:https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-BIN