Python 博士后-通过不同的目标和平均值获得数据-到目前为止没有运气
主要问题:“目前我所有传感器的平均温度是多少?平均角度是多少?平均分贝级?” 所以我有一个python脚本,它每15分钟循环一次,用http get操作的数据填充postgres表(xmldata)。此表很可能有1000000多条记录。此表和数据如下所示:Python 博士后-通过不同的目标和平均值获得数据-到目前为止没有运气,python,postgresql,Python,Postgresql,主要问题:“目前我所有传感器的平均温度是多少?平均角度是多少?平均分贝级?” 所以我有一个python脚本,它每15分钟循环一次,用http get操作的数据填充postgres表(xmldata)。此表很可能有1000000多条记录。此表和数据如下所示: fieldtest2=> select * from xmldata limit 7; id | time | ddinstancename | dcchannelname | dcdint
fieldtest2=> select * from xmldata limit 7;
id | time | ddinstancename | dcchannelname | dcdintegervalue
----+----------------------------+----------------+---------------+-----------------
1 | 2014-02-18 12:51:00.561153 | targ_4079E741 | AD1 | 641
2 | 2014-02-18 12:51:04.568751 | targ_40971E83 | AD1 | 641
3 | 2014-02-18 12:51:08.535351 | targ_4079E741 | AD0 | 641
4 | 2014-02-18 12:51:12.90712 | targ_4079E741 | AD1 | 641
5 | 2014-02-18 12:51:16.863364 | targ_40971E83 | AD1 | 641
6 | 2014-02-18 13:15:48.109646 | targ_40971E83 | AD0 | 589
7 | 2014-02-18 13:15:48.463776 | targ_4079E741 | AD1 | 653
现在,我被卡住的部分。我想从每个uniquedInstanceName(由于表的大小,只能追溯到一到两个小时)中获取最新的dcdintegervalue,然后按dcchannelname对它们进行分组,并平均每组的dcdintegervalue。例如,基本上每个“AD1”都是一个温度读数。我想从每个唯一的ddinstancename获取AD1数据的最新捕获。在上面的示例中,这将是id为5和7的记录。然后我想平均他们的dcdintegervalues,所以641+653/2=647,并将该平均值保存到另一个表sensoraverage:
fieldtest2=> select * from sensoraverage;
id | time | dcchannelname | channelaverage
----+------+---------------+----------------
(0 rows)
所以基本上你得到了一个快照,现在,所有目标的平均温度是647,平均x角是111,平均db水平是234。。。等等
我一直在尝试一些变化,并在进行时“使其变得简单”,但下面的“硬代码”目前正在讨论的频道,没有顺序或限制,只是为了尝试让一些东西工作。我的想法是对每个dcchannelname进行单独的查询。但可能有更好的办法。我应该把它分成几个单独的查询吗
只有4个不同的dcchannelname。可能有数百个不同的ddinstancename
avgTemp_query = "INSERT into sensoraverage (dcChannelName, channelaverage) VALUES (('AD0'), (SELECT DISTINCT ddInstanceName, AVG(dcdIntegerValue) FROM xmldata WHERE dcChannelName='AD0'));"
我认为从我所读到的,distinct并没有按照我认为应该的方式运行。
任何指导都将不胜感激。
谢谢
迈克
更新:根据卢卡斯的回答,似乎很接近。我想我遇到的问题是时间戳。我想在卢卡斯的帖子中加上这句话,但是太长了
我想知道是否需要重新将这些记录项添加到xmldata中的时间戳,如果这可能是问题所在的话。以下是我的最新尝试(我也尝试了now()::date-100,试图用这种方式抓住任何不走运的东西):
尝试直接匹配实际上只会产生一个结果(见下表),但会产生一整套平均值。我还无法根据匹配确定使用什么值来弥补平均值。但我觉得就要结束了。我很抱歉格式化,但我把这些都放在一行中,通过我的终端运行
fieldtest2=> WITH distinct_instances AS(
SELECT ddInstanceName
FROM xmldata
WHERE time = '2014-02-18 12:51:00.561153'
GROUP BY ddInstanceName HAVING count(*) = 1)
SELECT dcChannelName, avg(dcdintegervalue)
FROM distinct_instances
JOIN xmldata ON xmldata.ddInstanceName = distinct_instances.ddInstanceName
GROUP BY dcChannelName
ORDER BY dcChannelName;
dcchannelname | avg
---------------+----------------------
AD0 | 621.5416666666666667
AD1 | 648.6153133797599644
AD2 | 258.8515185601799775
AD3 | 324.5770528683914511
(4 rows)
fieldtest2=> select * from xmldata WHERE time = '2014-02-18 12:51:00.561153';
id | time | ddinstancename | dcchannelname | dcdintegervalue
----+----------------------------+----------------+---------------+-----------------
1 | 2014-02-18 12:51:00.561153 | targ_4079E741 | AD1 | 641
(1 row)
我想这就是你要找的
-- first get a set of the distinct instances within the last time period (here it is 1 hour)
-- then join that result set back to the table and group it by the channel name
WITH distinct_instances AS(
SELECT
ddinstancename,
FROM xmldata
WHERE time > now() - '1 hour'::interval
GROUP BY ddinstancename
HAVING count(*) = 1
)
SELECT
dcchannelname,
avg(dcdintegervalue)
FROM distinct_instances
JOIN xmldata ON xmldata.ddinstancename = distinct_instances.ddinstancename
GROUP BY dcchannelname
ORDER BY dcchannelname
由于加入,您可能需要对
ddinstancename
和time
进行索引,以获得此查询的任何性能。非常感谢您的回复。我对它进行了测试,它返回的记录为零。我对它进行了修改,认为我把它缩小到了now()函数,我想知道它是否因为表中的“time”格式而找不到时间匹配?xmldata时间字段:“时间时间戳默认语句_TIMESTAMP()”。再次感谢。Mikei如果我用一个简单的=“2014-02-18 12:51:00.561153”替换>now()-“1小时”
,它将返回一个点击ok。now()-“1小时”::interval
将返回一个过去一小时的时间戳,如果查询使用您指定的时间戳工作,则在它正在查找的时间内没有唯一记录,或者数据没有更新。嗨。是的,我做过测试,试过“20天”之类的东西,但我想我需要做更多的测试。我会记下你的答案。再次感谢您的帮助。