Если я правильно понял, вы можете использовать оконные функции и агрегирование:
select customer_id, product_ts, count(*) as num_products_before
from (select t.*,
min(case when product = :product then timestamp end) over (partition by customerid) as product_ts
from t
) t
where timestamp < product_ts
group by customer_id, product_ts;