循环遍历表以与Postgres的group一起在SQL中创建一个新表

时间:2016-01-20 20:25:36

标签: sql postgresql group-by

假设一个表具有以下结构

product  |  day  |  transactionid  |  saleprice  |
------------------------------------------------ |
Apple    |   1   |   239849248     |    10       |
Apple    |   2   |   239834328     |    10       |
Apple    |   2   |   239849249     |    10       |
Apple    |   3   |   239849234     |    11       |
Banana   |   1   |   239843244     |    2        |
Banana   |   2   |   239843244     |    2        |
Banana   |   3   |   239843244     |    3        |
Banana   |   4   |   239843244     |    3        |
Orange   |   1   |   239234238     |    25       |
Orange   |   2   |   239234238     |    25       |
Orange   |   3   |   239234238     |    25       |
Orange   |   3   |   239234238     |    26       |
Orange   |   3   |   239234238     |    26       |
Orange   |   4   |   239234238     |    27       |

每天销售多种产品,以不同价格进行多次交易。对于每个产品,我对Min(SalePrice)的更改日志感兴趣(更改日志,因为我的数据很少更改)。以下查询为我提供了特定产品(例如Orange):

SELECT max(product), day, min(saleprice)
  FROM tableabove
  where product = 'Orange'
  group by day
  order by day asc;

给我:

product  |  day  |  minsaleprice  |
Orange   |   1   |       25       |
Orange   |   2   |       25       |
Orange   |   3   |       25       |
Orange   |   4   |       27       |

所以,我对我指定的产品有所需要,但现在我需要它。例如,对于橙色我只需要价格变化的日子(和第1天),这意味着第1天和第4天应该只有两行。我也不知道如何在表格中对所有产品进行迭代生成一个看起来如下的新表。

product  |  day  |  minsaleprice  |
Apple    |   1   |       10       |
Apple    |   3   |       11       |
Banana   |   1   |       2        |
Banana   |   3   |       3        |
Orange   |   1   |       25       |
Orange   |   4   |       27       |

感谢任何帮助。感谢。

2 个答案:

答案 0 :(得分:1)

我想你只想要lag()

select t.*
from (select t.*,
             lag(saleprice) over (partition by product order by day) as prev_saleprice
      from tableabove t
     ) t
where prev_saleprice is null pr prev_saleprice <> saleprice;

编辑:

如果您只想逐日进行更改,那么同样的想法可以使用其他聚合:

select t.*
from (select t.product, t.day, min(salesprice) as min_saleprice
             lag(min(saleprice)) over (partition by product order by day) as prev_minsaleprice
      from tableabove t
      group by t.product, t.day
     ) t
where prev_minsaleprice is null pr prev_minsaleprice <> minsaleprice;

答案 1 :(得分:0)

根据Gordon Linoff的指导,我能够按如下方式编写查询:

SELECT table2.* 
FROM (SELECT table1.*, lag(table1.minsaleprice) OVER(partition by product) as prev_price
FROM (SELECT product, day, MIN(saleprice) as minsaleprice FROM tableabove 
GROUP BY day, product ORDER BY product, day) 
as table1)
as table2
WHERE prev_price IS null OR prev_fee <> minsaleprice