Как выбрать строки, если клиент купил один и тот же продукт 3 раза подряд - PullRequest
0 голосов
/ 25 июня 2019

У меня есть 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».

Я использую MSSQL 2008 на Windows Server 2008.

Ответы [ 3 ]

1 голос
/ 25 июня 2019

Вы можете использовать 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';

Если в истории покупок может быть менее трех записей, измените условие с на:

having min(ph3.product_id) = max(ph3.product_id) and
       min(ph3.product_id) = 'AA' and
       count(*) = 3;
0 голосов
/ 25 июня 2019

Я бы начал с этого, чтобы упорядочить заказы по клиенту (в порядке убывания даты покупки) и назначить последовательный номер строки.

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
)
0 голосов
/ 25 июня 2019

Я полагаю, что вы могли бы использовать такую ​​конструкцию, чтобы получить максимальное количество последовательных заказов одного и того же продукта на клиента:

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

Используйте это в подзапросе и сгруппируйте его по cust_id, product_id и получите максимум (rn), и вы должны получить то, что ищете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...