返回第一次达到特定数字的行(postgres)

时间:2017-10-13 11:04:18

标签: sql postgresql conditional-statements postgresql-9.5

遇到障碍。

上下文:我正在使用PostgreSQL 9.5.8

我有一张表,如下所示,与客户'累积积分。该表每个客户有多行,因为它记录了每个点的变化(如事件表)。即客户1可以购买1个商品并累积10个积分,这是一行,然后在另一天花费其中一些积分并留下5个积分,这是另一行,然后再购买另一个积累并再累积10个积累到15显示为另一行。具有点数的这些行中的每一行都具有created_at列。

示例表:

Customer ID  created_at    no_points   row
123          17/09/2017    5           1
123          09/10/2017    8           2
124          10/10/2017    12          3
123          10/10/2017    15          4
125          12/10/2017    12          5
126          17/09/2017    6           6
123          11/10/2017    11          7
123          12/10/2017    9           8
127          17/09/2017    5           9
124          11/10/2017    5           10
125          13/10/2017    5           11
123          13/10/2017    12          12

我想跟踪客户第一次达到某个阈值,即> = 10分。它们超过10分并不重要,唯一的标准是我选择客户达到此阈值的第一时间。我还希望此查询获取行,其中客户第一次在上周时达到了10的阈值。

遵循这些规则,在上面的示例中,我希望我的查询选择第3,4和5行。

我尝试了以下查询:

SELECT  x.id,
        min(x.created_at)

FROM (

SELECT 
        p.id as id,
        p.created_at as created_at,
        p.amount as amount 

FROM "points" p 

WHERE p.amount >= 10  )  x 

WHERE x.created_at >= (now()::date - 7)
AND    x.created_at <   now()::date   

GROUP BY x.id 

我不确定我是否正在从我看到的结果集中检索正确的东西&amp;结果集很大,所以不明显。有人能感觉到检查吗?

提前致谢。

1 个答案:

答案 0 :(得分:0)

使用累积功能:

select p.*
from (select p.*,
             sum(num_points) over (partition by p.customer_id order by p.created_at) as cume_num_points
      from points p
     ) p
where cume_num_points >= 10 and
      (cume_num_points - num_points) < 10;

编辑:

我可能误解了这个问题。如果您只想要第一个中断,一个方法使用窗口函数:

select p.*
from (select p.*,
             lag(num_points) over (partition by p.customer_id order by p.created_at) as prev_num_points
      from points p
     ) p
where num_points >= 10 and
      prev_num_points < 10;

或者,没有子查询:

select distinct on (p.customer_id) p.*
from customers p
where num_points >= 10
order by p.customer_id, p.created_at;