Home > Enterprise >  SQL Developer Identify those customers which purchased two particular products where one product was
SQL Developer Identify those customers which purchased two particular products where one product was

Time:06-29

I would really appreciate some help with a query I'm struggling with.

I have created a number of joins in order to create a table of what products each customer bought on each date. Each transaction is on each row.

I want to find those customers which have both purchased product A and B where product B was purchased after Product A. I would then like the output to show only the Customer IDs that meet this criteria.

So in the example below customer ID jones and blogs should appear on my output because they both purchased product ID A and B where A was purchased first. Lane wont make the list because they have not purchased the stated products or in the correct order. So far I have tried using the where and having clause as well as group by to no avail.

Sample Data

Purchase Table

customer ID Product ID Transaction Date
jones A 20/06/2022
jones B 26/06/2022
lane C 15/06/2022
lane A 14/06/2022
jones C 21/06/2022
blogs A 05/06/2022
blogs B 21/06/2022

Expected output

customer ID
jones
blogs

I hope that makes sense!

CodePudding user response:

select distinct a.CustomerId
from myTable a 
where a.ProductId = 'A' and 
 exists (select * from myTable b 
            where a.CustomerId = b.CustomerId  
              and b.ProductId = 'B' 
              and a.TransactionDate < b.TransactionDate);

CodePudding user response:

From Oracle 12, you can use MATCH_RECOGNIZE to perform row-by-row pattern matching:

SELECT customer_id
FROM   (SELECT * FROM purchase WHERE product_id IN ('A', 'B'))
MATCH_RECOGNIZE (
  PARTITION BY customer_id
  ORDER     BY transaction_date
  PATTERN ( ^ a  b )
  DEFINE
    a AS product_id = 'A',
    b AS product_id = 'B'
);

Which, for the sample data:

CREATE TABLE purchase (customer_ID, Product_ID, Transaction_Date) AS
SELECT 'jones', 'A', DATE '2020-06-20' FROM DUAL UNION ALL
SELECT 'jones', 'B', DATE '2020-06-26' FROM DUAL UNION ALL
SELECT 'lane',  'C', DATE '2020-06-15' FROM DUAL UNION ALL
SELECT 'lane',  'A', DATE '2020-06-14' FROM DUAL UNION ALL
SELECT 'jones', 'C', DATE '2020-06-21' FROM DUAL UNION ALL
SELECT 'blogs', 'A', DATE '2020-06-05' FROM DUAL UNION ALL
SELECT 'blogs', 'B', DATE '2020-06-21' FROM DUAL;

Outputs:

CUSTOMER_ID
blogs
jones

db<>fiddle here

  • Related