SQL:累积总和达到标记时获取日期

时间:2016-08-04 17:54:36

标签: sql postgresql date amazon-redshift

我有一个表格格式如下:

   APP_iD|  Date       |   Impressions
    113  2015-01-01     10
    113  2015-01-02     5
    113  2015-01-03     50
    113  2015-01-04     35
    113  2015-01-05     30
    113  2015-01-06     75

现在,我需要知道这些展示的累计总和超过65/100/150的日期,依此类推。 我尝试使用CASE WHEN语句:

CASE WHEN SUM(impressions) >100
     THEN date

但它不会对列中的数据求和。它只是对单个行进行检查。

我的最终结果应如下:

APP_iD  | Date_65   | Date_100   | Date_150
113       2015-01-03  2015-01-04   2015-01-06

有谁知道怎么做? 这甚至可能吗?

3 个答案:

答案 0 :(得分:3)

使用sum()over()获取运行总和并使用case表达式检查所需的值。最后聚合结果以获得每个app_id一行。

select app_id,max(dt_65),max(dt_100),max(dt_150) 
from (
select app_id
,case when sum(impressions) over(partition by app_id order by dt) between 65 and 99 then dt end dt_65
,case when sum(impressions) over(partition by app_id order by dt) between 100 and 149 then dt end dt_100
,case when sum(impressions) over(partition by app_id order by dt) >= 150 then dt end dt_150
from t) x
group by app_id

答案 1 :(得分:1)

with c as (
    select
        app_id, date,
        sum(impressions) over (partition by app_id order by date) as c
    from t
)
select app_id, s65.date, s100.date, s150.date
from
    (
        select distinct on (app_id) app_id, date
        from c
        where c >= 65 and c < 100
        order by app_id, date
    ) s65
    left join
    (
        select distinct on (app_id) app_id, date
        from c
        where c >= 100 and c <150
        order by app_id, date
    ) s100 using (app_id)
    left  join
    (
        select distinct on (app_id) app_id, date
        from c
        where c >= 150
        order by app_id, date
    ) s150 using (app_id) 
;
 app_id |    date    |    date    |    date    
--------+------------+------------+------------
    113 | 2015-01-03 | 2015-01-04 | 2015-01-06

没有支点:

select distinct on (app_id, break) app_id, break, date
from (
    select *,
        case
            when c < 100 then 65
            when c < 150 then 100
            else 150
        end as break
    from (
        select
            app_id, date,
            sum(impressions) over (partition by app_id order by date) as c
        from t
    ) t
    where c >= 65
) t
order by app_id, break, date
;
 app_id | break |    date    
--------+-------+------------
    113 |    65 | 2015-01-03
    113 |   100 | 2015-01-04
    113 |   150 | 2015-01-06

答案 2 :(得分:0)

您可以尝试此操作以获得所需的结果。

    with t as (select app_id, date, sum(Impressions) 
     over (partition by app_id order by date) AS s from tbl)
        select app_id, 
                min(date_65) AS date_65 , 
                min(date_100) AS date_100, 
                min(date_150) AS date_150
                -- more columns to observe other sum of Impressions
                from
                    (select app_id, 
                    CASE WHEN (s >= 65 and s < 100) THEN date END AS date_65,
                    CASE WHEN (s >= 100 and s < 150) THEN date END AS date_100,
                    CASE WHEN (s >= 150 ) THEN date END AS date_150
                    -- more cases to observe other sum of Impressions    
                    from t) q 
                    group by q.app_id

如果您想观察更多的展示次数,只需添加更多条件