为了解决这个问题,我想我们可以先找到一种方法,给定一个时间戳,找出它属于哪个刻钟。例如,小时08:38
属于季度08:30
,08:51
到08:45
,等等。
为此,我们可以使用如下函数:
CREATE FUNCTION date_trunc_quarter(timestamp )
RETURNS TIMESTAMP
LANGUAGE SQL
IMMUTABLE
AS $$
SELECT * FROM
generate_series(
date_trunc('hour',$1),
date_trunc('hour',$1)+interval '1hour',
interval '15min'
) AS gen(quarter)
WHERE gen.quarter < $1
ORDER BY gen.quarter
DESC LIMIT 1
$$;
它使用该generate_series
函数在与给定时间戳(例如 08:38)相同的小时内生成所有四个季度(例如 08:00、08:15、08:30 和 08:45),得到它使用的给定小时众所周知的date_trunc
功能。然后,它只过滤小于给定时间戳的四分之一,对其进行排序并获得较大的四分之一。由于它总是最多只有四个值,因此对其进行排序并不是什么大问题。
现在,您可以像这样轻松查询:
SELECT date_trunc_quarter(tstart) AS quarter, count(*)
FROM agenda
GROUP BY quarter
ORDER BY quarter;
我认为它已经足够快了,为了让它更快,你可以在议程上创建一个表达式索引:
CREATE INDEX idx_agenda_quarter ON agenda ((date_trunc_quarter(tstart)));
请参阅这个带有自包含测试用例的小提琴。