1

How do I display the customer_id of customers who bought products A and B, but didn’t buy product C, ordered by ascending customer ID.

enter image description here

I tried the below code, but does not give me any result.

select customer_id, product_name from orders where customer_id = 'A' and 'product_name '= 'B'

4 Answers 4

1
select customer_id from orders where product_name = 'A'
intersect
select customer_id from orders where product_name = 'B'
except
select customer_id from orders where product_name = 'C'
Sign up to request clarification or add additional context in comments.

3 Comments

Oh .. oh ...this one! I like it so much better than my answer! Especially because intersect would handle any duplicates. Nice!
@TroyWitthoeft Just A ∩ B \ C using set algebra notation :) But another question: how it is efficient for real data?
Well, that effecincy depends on plenty of other factors. How is the data is arranged? Are the columns we are querying evenly distributed inside the table? Which columns have indices? Whch database engine are we using? Lots of variables. Without knowing those, this answer works because it is succinct and clear. Set-based algebra for the win.
0

You can use analytical function as follows:

Select * from 
(select customer_id, product_name ,
       Count(distinct case when product_name in ('A','B') then product_name end) 
             Over (partition by customer_id) as cntab ,
       Count(case when product_name = 'C' then product_name end) 
             Over (partition by customer_id)  as cntc 
  from orders t) t
 Where cntab = 2 and cntc = 0;

Comments

0

One method use exists and not exists:

select o.*
from orders o
where exists (select 1
              from orders o2
              where o2.customer_id = o.customer_id and o2.product_name = 'A'
             ) and
      exists (select 1
              from orders o2
              where o2.customer_id = o.customer_id and o2.product_name = 'B'
             ) and
      not exists (select 1
                  from orders o2
                  where o2.customer_id = o.customer_id and o2.product_name = 'C'
                 )
order by customer_id;
  

Comments

0

To me, this query reads well ...

SELECT customer_id
FROM (
    SELECT TableA.customer_id
    FROM (
        SELECT customer_id
        FROM orders
        WHERE product_name = 'A' 
    ) AS TableA
    INNER JOIN (
        SELECT customer_id
        FROM orders 
        WHERE product_name = 'B'
    ) AS TableB
    ON TableA.customer_id = TableB.customer_id
) AS TableX
WHERE customer_id NOT IN (SELECT customer_id FROM orders WHERE product_name = 'C')

Explanation. Get a list of customer ids that bought products A and B with self inner join. Then, pare that list down by removing any rows where those customers bought product C.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.