在postgresql

时间:2018-09-27 00:13:14

标签: postgresql max

postsql查询中有三个字段,如下所示:

point     |      time a         |      time b
----------+---------------------+--------------------
     1    |2018-09-27 00:00:00 | 2018-09-26 00:00:00  
     1.5  |2018-09-27 00:00:00 | 2018-09-25 00:00:00  
     1.75 |2018-09-27 00:00:00 | 2018-09-24 00:00:00  
     1.25 |2018-09-27 00:00:00 | 2018-09-23 00:00:00
     2    |2018-09-28 00:00:00 | 2018-09-26 00:00:00  
     2.5  |2018-09-28 00:00:00 | 2018-09-25 00:00:00  
     2.7  |2018-09-28 00:00:00 | 2018-09-24 00:00:00  
     2.1  |2018-09-28 00:00:00 | 2018-09-23 00:00:00 

现在时间a具有4个常数值,并且与时间b相关的时间字段不同,如上所示。

如何查询以查找每个不同时间的最大时间b字段的值?

我知道之前提到的建议应该做:

row_number()OVER(按时间划分,按时间b划分顺序)。但是,如果有多余的字段,在应用此方法时会遇到很多麻烦。

所需的postgresql查询输出为:

point  |  time a             |      time b
-------+---------------------+--------------------
 1     |2018-09-27 00:00:00 | 2018-09-26 00:00:00  
 2     |2018-09-28 00:00:00 | 2018-09-26 00:00:00  

如何调整上面的查询以获得上面想要的结果?

3 个答案:

答案 0 :(得分:0)

您可以使用Windows功能。像这样:

select time_a, time_b
from (select time_a, time_b, row_number() 
  over (partition by time_a order by time_b DESC) from times)t
where row_number = 1

对于每组time_a,您将获得time_b的每个值的行号。由于已订购,因此最大数量为第一。最后,您需要一个外部选择进行过滤。

如果要在表中显示任何其他字段,这种方法比仅进行分组更灵活。

答案 1 :(得分:0)

如果您将收到的答案更改为问题,则答案可能会失去意义。这是原始问题的答案:

在标准SQL中,您应按time_a对行进行分组,并使用汇总max(time_b)

select time_a, max(time_b) as time_b
from data
group by time_a
order by time_a;

或者,您可以使用distinct on(这是Postgres的特定功能):

select distinct on (time_a) time_a, time_b
from data
order by time_a, time_b desc;

更新:

第二个查询的优点是允许您从具有最大值的行中选择多个列,例如:

select distinct on (time_a) point, time_a, time_b
from data
order by time_a, time_b desc;

 point |       time_a        |       time_b        
-------+---------------------+---------------------
     1 | 2018-09-27 00:00:00 | 2018-09-26 00:00:00
     2 | 2018-09-28 00:00:00 | 2018-09-26 00:00:00
(2 rows)    

Working example in rextester.

答案 2 :(得分:0)

demo: db<>fiddle

您可以GROUP BY trunc(point)首先将point的小数部分截断,然后将整数部分分组。

SELECT trunc(point), max(time_a), max(time_b) 
FROM times
GROUP BY trunc(point)

如果您确定time_apoint是恒定的(如示例中所示),则可以写为:

SELECT trunc(point), time_a, max(time_b) 
FROM times
GROUP BY trunc(point), time_a

否则,您可以在point列上使用time_a独立版本:

SELECT trunc(MIN(point)), time_a, max(time_b) 
FROM times
GROUP BY time_a