我有一张包含产品部分的表格。
__________________________________
| 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|
-----------------------------------------------------------
答案 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 sets,Filter
聚合之前的结果可以显着降低成本。所以添加
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;