如何获得最小和最大请求​​的时间?

时间:2017-06-12 06:45:08

标签: sql postgresql

我有一张包含产品部分的表格。

__________________________________
| SECTION| PRICE |     TIME      |
|--------------------------------|
|  sec1  |   10  | 06-12-17 12:00|
|  sec2  |   20  | 06-12-17 12:01|
|  sec1  |   20  | 06-12-17 12:02|
|  sec1  |   30  | 06-12-17 12:03|
|  sec2  |   30  | 06-12-17 12:04|
----------------------------------

我需要每个部分都有最小值,最大值和平均值。我做到了。

SELECT MAX(PRICE), MIN(PRICE), AVG(PRICE) FROM table1 GROUP BY SECTION;

我还需要一个最低和最高价格的销售时间。如果最大的销售是在不同的时间,我需要其中任何一个。如何在一张桌子上得到它?

___________________________________________________________
| SECTION| MIN | MAX | AVG |  TIME OF MAX   |  TIME OF MIN |
|----------------------------------------------------------|
|  sec1  | 10  |  30 |  20 | 06-12-17 12:03 |06-12-17 12:00|
|  sec2  | 20  |  30 |  25 | 06-12-17 12:04 |06-12-17 12:01|
-----------------------------------------------------------

3 个答案:

答案 0 :(得分:2)

使用没有tripple join的窗口函数:

t=# WITH a as (
SELECT
      SECTION
    , MAX(PRICE) over w
    , MIN(PRICE) over w
    , AVG(PRICE) over w
    , TIME t, price
    , case when MAX(PRICE) over w = price then TIME end maxt
    , case when MIN(PRICE) over w = price then TIME end mint
FROM s154
WINDOW w as (partition by section)
)
select DISTINCT
      SECTION
    , MAX
    , MIN
    , AVG
    , max(maxt) over (partition by section)
    , min(mint) over (partition by section)
from a
;
 section  | max | min |         avg         |         max         |         min
----------+-----+-----+---------------------+---------------------+---------------------
   sec1   |  30 |  10 | 20.0000000000000000 | 2017-06-12 12:03:00 | 2017-06-12 12:00:00
   sec2   |  30 |  20 | 25.0000000000000000 | 2017-06-12 12:04:00 | 2017-06-12 12:01:00
(2 rows)

同样正如Abelisto所指出的那样,on larger data setsFilter聚合之前的结果可以显着降低成本。所以添加

where maxt is not null or mint is not null
建议

到最后。

答案 1 :(得分:1)

您正在寻找类似Oracle KEEP FIRST的东西,它只能在PostgreSQL中使用窗口函数进行模拟:

select
  section,
  min(price),
  max(price),
  avg(price),
  max(case when rnk_max = 1 then time end) as time_of_max,
  max(case when rnk_min = 1 then time end) as time_of_min
from
(
  select 
    section, 
    price, 
    time,
    rank() over (partition by section order by price desc) as rnk_max,
    rank() over (partition by section order by price) as rnk_min
  from sections
) ranked
group by section;

我正在使用RANK,因此您可以获得最低或最高价格的多条记录。使用max(case ...),我将从集合中获取最新日期。

答案 2 :(得分:0)

假设:最低和最高价格只能在独特时间内发生。

试试这个(我选择易于理解而不是高效查询):

SELECT      sq.*
            , tmin.time AS minTime
            , tmax.time AS maxTime
FROM        (
            SELECT      section
                        , MAX(price)    AS maxPrice
                        , MIN(price)    AS minPrice
                        , AVG(price)    AS avgPrice
            FROM        table1
            GROUP BY    section
        ) AS sq
    INNER JOIN table1 AS tmin
        ON tmin.section = sq.section
        AND tmin.price  = sq.minPrice
    INNER JOIN table1 AS tmax
        ON tmax.section = sq.section
        AND tmax.price  = sq.minPrice;