Sql 用时间序列摘要数据填空
我试图为“每n分钟接收一个传感器的数据”画一个简单的(读作:快速的)火花线 数据非常简单,它是给定时间戳的一个或多个读数,由传感器的mac地址标识:Sql 用时间序列摘要数据填空,sql,postgresql,group-by,time-series,Sql,Postgresql,Group By,Time Series,我试图为“每n分钟接收一个传感器的数据”画一个简单的(读作:快速的)火花线 数据非常简单,它是给定时间戳的一个或多个读数,由传感器的mac地址标识: # SELECT mac, ants, read_at FROM normalized_readings LIMIT 10; mac | ants | read_at -------------------+------+------------------------- f0:d1:a9:a0:fe
# SELECT mac, ants, read_at FROM normalized_readings LIMIT 10;
mac | ants | read_at
-------------------+------+-------------------------
f0:d1:a9:a0:fe:e7 | -87 | 2013-07-14 09:25:15.215
74:de:2b:fa:ca:cf | -69 | 2013-07-14 09:25:14.81
74:de:2b:fa:ca:cf | -69 | 2013-07-14 09:25:14.81
74:de:2b:fa:ca:cf | -69 | 2013-07-14 09:25:15.247
38:aa:3c:8f:a0:4f | -85 | 2013-07-14 09:25:21.672
38:aa:3c:8f:a0:4f | -87 | 2013-07-14 09:25:21.695
60:67:20:c8:bc:80 | -83 | 2013-07-14 09:25:26.73
60:67:20:c8:bc:80 | -81 | 2013-07-14 09:25:26.737
f0:d1:a9:a0:fe:e7 | -83 | 2013-07-14 09:25:36.207
f0:d1:a9:a0:fe:e7 | -91 | 2013-07-14 09:26:07.77
(10 rows)
我正试图想出一些类似的办法:
# SELECT
mac, date_trunc('minute', read_at) AS minute, COUNT(*)
FROM
normalized_readings
GROUP BY mac, minute LIMIT 10;
mac | minute | count
-------------------+---------------------+-------
00:08:ca:e6:a1:86 | 2013-07-14 16:22:00 | 6
00:10:20:56:7c:e2 | 2013-07-27 05:29:00 | 1
00:21:5c:1c:df:7d | 2013-07-14 09:44:00 | 1
00:21:5c:1c:df:7d | 2013-07-14 09:46:00 | 1
00:21:5c:1c:df:7d | 2013-07-14 09:48:00 | 1
00:24:d7:b3:31:04 | 2013-07-15 06:51:00 | 1
00:24:d7:b3:31:04 | 2013-07-15 06:53:00 | 3
00:24:d7:b3:31:04 | 2013-07-15 06:59:00 | 3
00:24:d7:b3:31:04 | 2013-07-15 07:02:00 | 3
00:24:d7:b3:31:04 | 2013-07-15 07:06:00 | 3
(10 rows)
但是请注意所有的空时段,我希望能够提取这些时段的0
,以指示传感器没有记录数据。
可能我只想显示过去12/24小时的数据,所以我想我可以通过选择过去12/24小时的人工日期(可能是1或5分钟)来强制执行此操作,对于每个分辨率,我必须查询读数表,并计算读数总数,但这听起来很可怕
有没有一种方法可以让我做我想做的事情,而不必强迫别人去做?就我所见,当我通过选择分钟进行分组时,我会自动从错误的一方进行分组?对于这种类型的查询,您需要一个生成所有“Mac”和“分钟”组合的驱动程序表。Postgres有一个很好的函数
generate_series()
,可以为每分钟获取一个计数器
因此,我们的想法是从所有Mac电脑开始,每分钟生成一个系列。然后使用驱动程序表中的左外部联接
,为每个值获取一行
with t as (
SELECT mac, date_trunc('minute', read_at) AS minute, COUNT(*) as cnt
FROM normalized_readings
GROUP BY mac, minute
LIMIT 10
)
select driver.mac, driver.minute, coalesce(cnt, 0)
from (select mac, minminute,
minminute + cast(cast(generate_series(0,
cast(extract(epoch from maxminute - minminute)/60 as int)
) as character varying
)||' minute' as interval
) as minute
from (select mac, min(minute) as minminute, max(minute) as maxminute
from t
group by mac
) macs
) driver left outer join
t
on t.mac = driver.mac and
t.minute = driver.minute
SQL小提琴是
我能看到的唯一问题是如何获得原始数据——
t
的定义。我仿效了问题中的例子。但是,这实际上没有意义。您有一个限额
,没有订单依据
。您应该按的顺序输入相应的对于这种类型的查询,您需要一个生成所有“mac”和“minutes”组合的驱动程序表。Postgres有一个很好的函数generate_series()
,可以为每分钟获取一个计数器
因此,我们的想法是从所有Mac电脑开始,每分钟生成一个系列。然后使用驱动程序表中的左外部联接
,为每个值获取一行
with t as (
SELECT mac, date_trunc('minute', read_at) AS minute, COUNT(*) as cnt
FROM normalized_readings
GROUP BY mac, minute
LIMIT 10
)
select driver.mac, driver.minute, coalesce(cnt, 0)
from (select mac, minminute,
minminute + cast(cast(generate_series(0,
cast(extract(epoch from maxminute - minminute)/60 as int)
) as character varying
)||' minute' as interval
) as minute
from (select mac, min(minute) as minminute, max(minute) as maxminute
from t
group by mac
) macs
) driver left outer join
t
on t.mac = driver.mac and
t.minute = driver.minute
SQL小提琴是
我能看到的唯一问题是如何获得原始数据——t
的定义。我仿效了问题中的例子。但是,这实际上没有意义。您有一个限额
,没有订单依据
。您应该按
订购相应的,谢谢Gordon,它们应该由mac订购,请在
处阅读。我随意加入了一个LIMIT 10
,为了不让50万条条目扼杀它,但你是对的<代码>限制
没有按订购真的没有意义。谢谢Gordon,它们应该由mac订购,请在
处阅读。我随意加入了一个LIMIT 10
,为了不让50万条条目扼杀它,但你是对的<代码>限制没有按顺序真的没有意义。