SQL 中的迭代求和
Posted
技术标签:
【中文标题】SQL 中的迭代求和【英文标题】:Iterative summations in SQL 【发布时间】:2013-03-14 20:33:17 【问题描述】:我在 Zabbix DB 中有值,每分钟加载一次。我需要一个查询来计算不同日期的每小时总计,例如在 2013 年 3 月 20 日以下,我会有一行 0:00 包含时间 >= 0:00 和
SELECT
SUM(CASE WHEN itemid = 23661
THEN value ELSE 0 END) Hits
FROM history_uint WHERE
clock >= EXTRACT(EPOCH FROM TIMESTAMP '2013-03-24 00:00:00')
AND clock < EXTRACT(EPOCH FROM TIMESTAMP '2013-03-24 01:00:00')
【问题讨论】:
在过去,我使用 MSSql 交叉连接到一个包含数字的表以充当迭代索引,然后根据该数字添加时间。像这样select adddate(hour, @date, NumbersTable.number) from NumbersTable
【参考方案1】:
您是否尝试过按小时对结果进行分组?
SELECT DATEPART(HOUR, timestamp) [HOUR]
, SUM(CASE WHEN itemid = 23661 THEN value ELSE 0 END) hits
FROM history_uint
WHERE clock >= EXTRACT(EPOCH FROM timestamp '2013-03-24')
AND clock < EXTRACT(EPOCH FROM timestamp '2013-03-25')
GROUP BY DATEPART(HOUR, timestamp);
【讨论】:
错误:“[”或附近的语法错误 LINE 1: SELECT DATEPART(HOUR, timestamp) [HOUR], ^ ********** Error ****** **** 错误:“[”处或附近的语法错误 SQL 状态:42601 字符:34 这个错误是因为提取日期时间列的小时部分的函数。不幸的是,我不知道 postgre 中的适当函数(这是来自 SQLServer),但如果你知道正确的函数,这个解决方案应该可以工作。如果您遇到困难,请告诉我。【参考方案2】:类似:
select '2013-03-20'::date + delta * '1 hour'::interval
from generate_series(0,23) g(delta)
【讨论】:
这只会生成一系列小时......你如何让它在一列中给出时间戳和第二列中该小时的值计数?【参考方案3】:select
date_trunc('hour', clock) "hour",
sum((itemid = 23661)::integer) hits
from history_uint
group by 1
order by 1
或所有时间都已满:
select
s.hour, count(itemid = 23661 or null) hits
from
(
select date_trunc('hour', clock) "hour", itemid
from history_uint
) h
right join (
select date_trunc('hour', d) "hour"
from generate_series (
(select min(clock::date)),
(select max(clock)::date + 1) - interval '1 hour',
'1 hour'
) s(d)
) s on s.hour = h.hour
group by 1
order by 1
【讨论】:
我认为 date_trunc 不适用于时钟,因为时钟不是时间戳对象而是整数(纪元时间)以上是关于SQL 中的迭代求和的主要内容,如果未能解决你的问题,请参考以下文章