Python 博士后-通过不同的目标和平均值获得数据-到目前为止没有运气

Python 博士后-通过不同的目标和平均值获得数据-到目前为止没有运气,python,postgresql,Python,Postgresql,主要问题:“目前我所有传感器的平均温度是多少?平均角度是多少?平均分贝级?” 所以我有一个python脚本,它每15分钟循环一次,用http get操作的数据填充postgres表(xmldata)。此表很可能有1000000多条记录。此表和数据如下所示: fieldtest2=> select * from xmldata limit 7; id | time | ddinstancename | dcchannelname | dcdint

主要问题:“目前我所有传感器的平均温度是多少?平均角度是多少?平均分贝级?”

所以我有一个python脚本,它每15分钟循环一次,用http get操作的数据填充postgres表(xmldata)。此表很可能有1000000多条记录。此表和数据如下所示:

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天”之类的东西,但我想我需要做更多的测试。我会记下你的答案。再次感谢您的帮助。