2016-11-18 57 views
1

我有上升的時間戳一些數值數據如下:如何在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來計算這個數字。

+0

你能詳細解釋邏輯嗎?你應該找到所有的最大值,並在金額變爲0之前將它們相加一天? –

+0

不一定爲0.它可以降到任何值並再次提取,但我們需要添加兩個(或更多)最高的數字。 – CodingInCircles

回答

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 ║ 
╚════════╧════════════════════════╝ 

聲明:我不確定您想在當天穿越什麼。

+0

我們不知道我們將如何處理午夜邊緣情況,要麼告知真相:)但這是一個開始,它看起來像是正確的。感謝你! :) – CodingInCircles

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; 
+0

雖然這是較早的答案,但它只返回MAX,而不是多個最大值。 Abelisto的回答給了我我想要的。 – CodingInCircles

+0

@CodingInCircles。 。 。如果你想要所有的最大值,那麼使用'rank()'而不是'row_number()'。你的問題在一天內出現多個極大值模糊不清,你的樣本數據沒有這樣的例子。 –