2017-06-12 79 views
0

我有一個產品部分的表格。如何獲取最小和最大請求​​的時間?

__________________________________ 
| 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| 
----------------------------------------------------------- 

回答

2

加入:

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 

到最後推薦。

+0

如果在最後一個查詢中添加「maxt不爲空或mint不爲空」,它可能會更快一點(在我的測試中大約有兩次)。 – Abelisto

+0

true - 過濾器應該更加豐富 - 謝謝! –

+0

PS:http://dbfiddle.uk/?rdbms=postgres_9.5&fiddle=b5fcf4bf9e7206c78f16a22bb0b1f0ae – Abelisto

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; 
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 ...)我會從集的最新日期。

相關問題