如何在Redshift中找到每日局部最大值的总和?

时间:2016-11-18 17:52:33

标签: sql postgresql sum max amazon-redshift

我有一些带有升序时间戳的数字数据,如下所示:

amount | received_at
_______|______________
30     | 2016-11-18 10:21:35 AM
60     | 2016-11-18 10:22:05 AM
90     | 2016-11-18 10:22:35 AM
120    | 2016-11-18 10:23:05 AM
150    | 2016-11-18 10:23:35 AM
160    | 2016-11-18 10:24:05 AM
0      | 2016-11-18 10:26:00 AM
20     | 2016-11-18 10:26:20 AM
40     | 2016-11-18 10:26:40 AM
55     | 2016-11-18 10:26:50 AM

我需要添加160和55才能获得总数。这不仅限于两个数字,但对于给定的一组列,可以是每天需要添加的多个这样的最大值。对此有一个简单(足够)的解决方案吗?

我正在使用Redshift来计算这个数字。

2 个答案:

答案 0 :(得分:1)

假设您的表格为create table t(amount int, received_at timestamptz);

1)存储功能:

create function foo() returns setof t language plpgsql immutable as $$
declare
  r t;
  c t;
begin
  r := null;
  for c in (select * from t order by received_at) loop
    if r is null or r.amount < c.amount then
      r := c;
    else
      return next r;
      r := c;
    end if;
  end loop;
  if r is not null then
    return next r;
  end if;
end $$;

select * from foo();

2)窗口功能:

with cte as (
  select
    amount,
    received_at,
    case 
      when coalesce(lead(amount) over (order by received_at), 0) < amount then 1
      else 0 
    end as flag
  from t)
select amount, received_at from cte where flag = 1;

结果:

╔════════╤════════════════════════╗
║ amount │      received_at       ║
╠════════╪════════════════════════╣
║    160 │ 2016-11-18 10:24:05+02 ║
║     55 │ 2016-11-18 10:26:50+02 ║
╚════════╧════════════════════════╝

免责声明:我不确定你在当天的十字路口想做什么。

答案 1 :(得分:0)

这是一种方法:

select sum(amount)
from (select t.*,
             row_number() over (partition by date_trunc('day', received_at) order by amount desc) as seqnum
      from t
     ) t
where seqnum = 1;