Я бы начал с этого, чтобы упорядочить заказы по клиенту (в порядке убывания даты покупки) и назначить последовательный номер строки.
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
)