如何获取postgreSQL中两个值之间的总计数

How to get the total count between two values in postgreSQL

我在一个列中有 3 个活动 (completed_order, email, viewed),我想计算每个 completed_order activity 之间发生了多少 email 个活动,并将它们保存在不同的专栏。 我写了这个查询:

SELECT  activity_id, ts, customer, activity ,
        case when activity = 'completed_order'      
        then count(*)filter (where activity = 'email' ) over (partition by customer order by ts )
        else null end as Aggregate_in_between
    FROM public.activity_stream as az1  where customer = 'Lehmanns Marktstand' order by ts ;

我通过上述查询得到以下结果。

activity_id ts customer activity agg_in_btw
11089 "1996-08-12 00:00:00+05" "Lehmanns Marktstand" "completed_order" 0
10279 "1996-08-13 00:00:00+05" "Lehmanns Marktstand" "completed_order" 0
11077 "1996-08-14 00:00:00+05" "Lehmanns Marktstand" "email"
11092 "1996-08-17 00:00:00+05" "Lehmanns Marktstand" "viewed_page"
11088 "1996-08-18 00:00:00+05" "Lehmanns Marktstand" "viewed_page"
10284 "1996-08-19 00:00:00+05" "Lehmanns Marktstand" "completed_order" 1
11078 "1996-08-20 00:00:00+05" "Lehmanns Marktstand" "email"
11079 "1996-08-21 00:00:00+05" "Lehmanns Marktstand" "email"
11080 "1996-10-21 00:00:00+05" "Lehmanns Marktstand" "email"
10343 "1996-10-31 00:00:00+05" "Lehmanns Marktstand" "completed_order" 4
11090 "1996-11-01 00:00:00+05" "Lehmanns Marktstand" "viewed_page"
11091 "1996-11-02 00:00:00+05" "Lehmanns Marktstand" "email"
10497 "1997-04-04 00:00:00+05" "Lehmanns Marktstand" "completed_order" 5
10522 "1997-04-30 00:00:00+05" "Lehmanns Marktstand" "completed_order" 5

我想要的结果应该是这样的

activity_id ts customer activity agg_in_btw
11089 "1996-08-12 00:00:00+05" "Lehmanns Marktstand" "completed_order" 0
10279 "1996-08-13 00:00:00+05" "Lehmanns Marktstand" "completed_order" 1
11077 "1996-08-14 00:00:00+05" "Lehmanns Marktstand" "email"
11092 "1996-08-17 00:00:00+05" "Lehmanns Marktstand" "viewed_page"
11088 "1996-08-18 00:00:00+05" "Lehmanns Marktstand" "viewed_page"
10284 "1996-08-19 00:00:00+05" "Lehmanns Marktstand" "completed_order" 3
11078 "1996-08-20 00:00:00+05" "Lehmanns Marktstand" "email"
11079 "1996-08-21 00:00:00+05" "Lehmanns Marktstand" "email"
11080 "1996-10-21 00:00:00+05" "Lehmanns Marktstand" "email"
10343 "1996-10-31 00:00:00+05" "Lehmanns Marktstand" "completed_order" 1
11090 "1996-11-01 00:00:00+05" "Lehmanns Marktstand" "viewed_page"
11091 "1996-11-02 00:00:00+05" "Lehmanns Marktstand" "email"
10497 "1997-04-04 00:00:00+05" "Lehmanns Marktstand" "completed_order" 0
10522 "1997-04-30 00:00:00+05" "Lehmanns Marktstand" "completed_order" 0

试试这个方法:

select  activity_id, ts, customer, activity ,
case when activity = 'completed_order' then
sum(case when activity='email' then 1 else 0 end) over (partition by customer,grp1)
else
null
end "Aggregate_in_between"
from (
select *, sum(grp) over (partition by customer order by ts) "grp1" from (
select *, case when activity='completed_order' then 1 else 0 end "grp" from activity_stream order by ts  
) t ) q

在这里你必须为每 completed_order 次出现创建一个组,他们计算每个组中的 email 次。

您可以根据自己的方便添加 where 子句

DEMO

这是一个分组问题。根据“已完成”的累积计数分配一个组。然后在每组内数数:

select a.*,
       count(*) filter (where activity = 'email') over (partition by co_grp)
from (select a.*,
             count(*) filter (where activity = 'completed_order') over (partition by customer order by ts) as co_grp
      from public.activity_stream a
      where customer = 'Lehmanns Marktstand'
     ) a
order by ts ; 

在您的示例数据中,您似乎只希望在已完成的订单行上执行此操作,因此为此使用 case 表达式:

select a.*,
       (case when activity = 'completed_order'
             then count(*) filter (where activity = 'email') over (partition by co_grp)
        end) as agg_in_btw
from (select a.*,
             count(*) filter (where activity = 'completed_order') over (partition by customer order by ts) as co_grp
      from public.activity_stream a
      where customer = 'Lehmanns Marktstand'
     ) a
order by ts ;