计算按某些行分组的出现次数

时间:2013-09-27 14:25:17

标签: sql postgresql count window-functions

我已经提出了一个查询,为我提供了没有库存的产品数量(我知道通过查看制造商返回的订单和一些状态代码),按产品,日期和存储,看起来像这样:

SELECT count(*) as out_of_stock, 
prod.id as product_id,
ped.data_envio::date as date,
opl.id as storage_id
from sub_produtos_pedidos spp
left join cad_produtos prod ON spp.ean_produto = prod.cod_ean
left join sub_pedidos sp ON spp.id_pedido = sp.id
left join pedidos ped ON sp.id_pedido = ped.id
left join op_logisticos opl ON sp.id_op_logistico = opl.id
where spp.motivo = '201' -- this is the code that means 'not in inventory'
group by storage_id,product_id,date

这产生了这样的答案:

 out_of_stock | product_id | date        | storage_id
--------------|------------|-------------|-------------
 1            | 5          | 2012-10-16  | 1
 5            | 4          | 2012-10-16  | 2

现在,我需要按产品和存储次数获取已停产2天或更长时间,5天或更长时间的产品数量等。
所以我想我需要对第一个查询进行新的计数,在一些定义的日间隔中聚合结果行。

我尝试查看Postgres中的日期时间函数(http://www.postgresql.org/docs/7.3/static/functions-datetime.html),但找不到我需要的内容。

2 个答案:

答案 0 :(得分:1)

可能是我没有正确回答你的问题,但看起来你需要利用子查询。

  

现在,我需要按产品和存储方式获取已停产2天或以上的产品的次数

所以:

SELECT COUNT(*), date, product_id FROM ( YOUR BIG QUERY IS THERE ) a
WHERE a.date < (CURRENT_DATE - interval '2' day)
GROUP BY date, product_id

答案 1 :(得分:0)

由于您似乎希望结果中的每一行,因此您无法进行汇总。请使用window function来获取每天的点数。众所周知的聚合函数count()也可以作为窗口聚合函数

SELECT current_date - ped.data_envio::date AS days_out_of_stock
      ,count(*) OVER (PARTITION BY ped.data_envio::date)
                                        AS count_per_days_out_of_stock
      ,ped.data_envio::date AS date
      ,p.id                 AS product_id
      ,opl.id               AS storage_id
FROM   sub_produtos_pedidos spp
LEFT   JOIN cad_produtos    p   ON p.cod_ean = spp.ean_produto
LEFT   JOIN sub_pedidos     sp  ON sp.id     = spp.id_pedido
LEFT   JOIN op_logisticos   opl ON opl.id    = sp.id_op_logistico
LEFT   JOIN pedidos         ped ON ped.id    = sp.id_pedido
WHERE  spp.motivo = '201'                   -- code for 'not in inventory'
ORDER  BY ped.data_envio::date, p.id, opl.id

排序顺序:产品首次缺货时间最长 请注意,您只需减去dates即可获得Postgres中的integer

如果你想要运行计数,那么或更多&#34; 行已经缺货或更多&#34;使用方法:

count(*) OVER (ORDER BY ped.data_envio::date) -- ascending order!
                                        AS running_count_per_days_out_of_stock

你在同一天得到相同的数,同龄人被混为一谈。