PSQL为每个id每分钟选择最大值,每个id每分钟多个值?

时间:2009-12-14 18:44:17

标签: sql select postgresql

给出一个如下表:

 sensor_id |          time          |  voltage
-----------+------------------------+------------
     12292 | 2009-12-01 00:50:04-07 |       2270
     12282 | 2009-12-01 00:50:04-07 |      93774
     12192 | 2009-12-01 00:50:04-07 |       9386
     12609 | 2009-12-01 00:50:05-07 |          0
     12566 | 2009-12-01 00:50:08-07 |          0
     12659 | 2009-12-01 00:50:19-07 |        540
     12660 | 2009-12-01 00:50:19-07 |        550
     12661 | 2009-12-01 00:50:19-07 |        510
     12656 | 2009-12-01 00:50:19-07 |      30240
     12657 | 2009-12-01 00:50:19-07 |      14930
     12658 | 2009-12-01 00:50:19-07 |      17420
     11820 | 2009-12-01 00:50:26-07 |       1.38
     11832 | 2009-12-01 00:50:28-07 |      1.359
     12768 | 2009-12-01 00:50:33-07 |     636588
     13192 | 2009-12-01 00:50:34-07 |      1.401
         .                        .            .
         .                        .            .
         .                        .            .

有时你会得到如下记录:

     12292 | 2009-12-01 00:50:04-07 |       2270
     12282 | 2009-12-01 00:50:04-07 |      93774
     12192 | 2009-12-01 00:50:04-07 |       9386
     12609 | 2009-12-01 00:50:05-07 |          0
     12566 | 2009-12-01 00:50:08-07 |          0
     12659 | 2009-12-01 00:50:19-07 |        540     *
     12659 | 2009-12-01 00:50:45-07 |        541     *
     12660 | 2009-12-01 00:50:19-07 |        550
     12661 | 2009-12-01 00:50:19-07 |        510
     12656 | 2009-12-01 00:50:19-07 |      30240
     12657 | 2009-12-01 00:50:19-07 |      14930
     12658 | 2009-12-01 00:50:19-07 |      17420
     11820 | 2009-12-01 00:50:26-07 |       1.38     #
     11832 | 2009-12-01 00:50:28-07 |      1.359
     11820 | 2009-12-01 00:50:28-07 |        1.3     #
     12768 | 2009-12-01 00:50:33-07 |     636588
     13192 | 2009-12-01 00:50:34-07 |      1.401
         .                        .            .
         .                        .            .
         .                        .            .

注意盯着和散列的线条。每个都是在同一分钟内读取的读数,但我每分钟只需要一个值,最好是最大值。 我试过了:


select sensor_id, read_time, voltage 
from table 
where (sensor_id, read_time) 
in (select sensor_id, max(read_time) 
    from table 
    group by sensor_id);

这显然不起作用,但我认为我走在正确的轨道上?

<小时/> 对于那些感兴趣的人,最终的代码如下:


select sensor_id, date_trunc('minute', read_time), max(voltage) 
from table 
group by sensor_id, date_trunc('minute', read_time) 
order by date_trunc('minute', read_time); 
 

3 个答案:

答案 0 :(得分:2)

这样的东西
SELECT sensor_id, date_trunc('minute',time), max(voltage)
FROM t
GROUP BY sensor_id, date_trunc('minute',time)

可能是你在找什么?

答案 1 :(得分:1)

你必须按照一个表达式来“分组”你想要的最大值的一分钟桶:

select sensor_id, DateHourMinuteFunction(read_time), Max(voltage) 
from table 
Group By sensor_id, DateHourMinuteFunction(read_time)

其中DateHourMinuteFunction(read_time)是数据库中的某个函数或Sql Expression,它将返回同一分钟内任何read_time相同的表达式(即,它需要去除秒值)

您的数据库可以将日期时间转换为字符串吗?如果是这样,那么至少写一个表达式将其转换为字符串,格式化为月日,年,小时,秒,然后剥去秒部分...

假设你在datetime列中已有的是一个字符串,那么只需在其上使用子字符串......

select sensor_id, SubString(Cast(read_time as varChar(22)), 0, 16), Max(voltage) 
from table 
Group By sensor_id, SubString(Cast(read_time as varChar(22)), 0, 16)

答案 2 :(得分:0)

我使用的是MS SQL,而不是Oracle,因此我不知道所有的Oracle日期函数都在我的头脑中。你基本上想要做的是加入一个表,你的分钟按开始和结束时间细分。它既可以作为一种子查询动态生成,也可以在数据库中拥有包含所有范围的永久表。然后代码可以解决这个问题:

SELECT
     T.sensor_id,
     DR.start_time AS read_time_minute,
     MAX(T.voltage) AS voltage
FROM
     Date_Ranges DR
INNER JOIN My_Table T ON
     T.read_time BETWEEN DR.start_time AND DR.end_time
WHERE
     DR.start_time >= <report start time> AND
     DR.start_time < <report end time>

如果您想要包含未进行测量的时间,请将INNER JOIN更改为LEFT OUTER JOIN。开始和结束时间看起来像'2009-12-14 00:00:00','2009-12-14 00:02:00'