如果客户连续3次购买相同的产品,该如何选择行

时间:2019-06-25 15:04:06

标签: sql sql-server

我有2个表,[customer_list]和[purchase_history]。 我想查找最近三次连续三次购买特定产品的所有客户的列表。

下面的表格示例:

customer_list          purchase_history
id |  name             id | cust_id| product_id | purchase_date
1  |  Alan              1 |    1   |     AA     |  2019-06-05
2  |  Bob               2 |    1   |     BB     |  2019-1-13
3  |  Carol             3 |    2   |     CC     |  2018-11-23
4  |  David             4 |    1   |     AA     |  2017-03-12
                        5 |    3   |     CC     |  2019-09-25
                        6 |    1   |     FF     |  2019-04-31
                        7 |    1   |     AA     |  2019-02-14
                        8 |    4   |     AA     |  2019-03-05
                        9 |    4   |     AA     |  2019-04-10
                       10 |    2   |     AA     |  2019-02-24
                       11 |    4   |     AA     |  2019-05-16

我正在使用类似于下面的代码,但是希望有人也能帮助您

select * from customer_list t1 where EXISTS(
    select * from purchase_history t2 where **latest 3 product_id** is like 'AA' )

我的最终结果应该是这样的:

  customer_list
  id  | name
  4   | David

结果中仅应显示“大卫”,因为他最近的最近3次购买是选择了“ AA”的特定产品。

我正在Windows Server 2008上运行MSSQL2008。

3 个答案:

答案 0 :(得分:1)

您可以使用cross apply和聚合:

select c.id
from customer_list c cross apply
     (select top (3) ph.*
      from purchase_history ph
      where ph.cust_id = c.id
      order by ph.purchase_date desc
     ) ph3
group by c.id
having min(ph3.product_id) = max(ph3.product_id) and
       min(ph3.product_id) = 'AA';

如果购买历史记录中的记录少于三个,则将hading子句更改为:

having min(ph3.product_id) = max(ph3.product_id) and
       min(ph3.product_id) = 'AA' and
       count(*) = 3;

答案 1 :(得分:0)

我想您可以使用这样的构造来获得每个客户相同产品的最大顺序订单量:

ROW_NUMBER() OVER (PARTITION BY cust_id, product_id ORDER BY cust_id ASC, purchase_date DESC) as rn

在子查询中使用它,并按cust_id,product_id对其进行分组并获得max(rn),那么您应该拥有所需的内容。

答案 2 :(得分:0)

首先,我要按客户的顺序对订单进行排序(按降序排列),并分配一个连续的行号。

select ROW_NUMBER() OVER (PARTITION BY cust_id ORDER BY cust_id ASC, purchase_date DESC) RowNumber, *
from purchase_history

(您不需要所有字段。我只是在其中留了*,以便于验证。)

在外部查询中将其括起来,该查询对派生的行号进行筛选,以将最多3个最新订单(按客户)和按客户(产品)分组。如果该客户的所有最近3个订单都是相同的产品,则HAVING COUNT(*) = 3将为您带来所需的客户。然后,您可以加入或子查询以获取customer_list列。

这是整个查询:

select * from customer_list where id in (
select cust_id  from (
select ROW_NUMBER() OVER (PARTITION BY cust_id ORDER BY cust_id ASC, purchase_date DESC) RowNumber, 
cust_id, product_id
from purchase_history
) s1
where RowNumber <= 3
group by cust_id, product_id
having count(*) = 3
)