Reputation: 96
FX., Given tables for baskets and fruits, looking for a query that returns the basket_id that contains ONLY the two specific fruit.
EX table: fruits
basket_id | fruit
_________________
1 | apple
1 | orange
1 | pear
2 | apple
2 | orange
3 | apple
3 | pear
Given the above table, I'm looking for a query that returns the basket_id that ONLY contains the fruits "apple" and "orange", which would be row 2 only. Basket id 1 should be excluded because it also contains "pear".
Help with this would be most appreciated.
Upvotes: 0
Views: 123
Reputation: 15846
If it is possible to use the list of items as an ordered list you want to select like 'apple,orange'
, then you can use following.
SELECT f.basket_id, f.fruit
FROM fruits f
INNER JOIN (
SELECT basket_id, GROUP_CONCAT(fruit order by fruit) as a
FROM fruits
GROUP BY basket_id
HAVING a = 'apple,orange'
) f1 ON f.basket_id = f1.basket_id
Here is the fiddle.
Upvotes: 0
Reputation: 549
SELECT DISTINCT basket_id
FROM fruits f
WHERE
NOT EXISTS (SELECT 1 FROM fruits f1 WHERE f.basket_id=f1.basket_id AND f1.fruit NOT IN ('apple', 'orange'))
AND
(SELECT count(*) FROM fruits f2 WHERE f.basket_id=f2.basket_id AND f2.fruit='apple')=1
AND
(SELECT count(*) FROM fruits f3 WHERE f.basket_id=f3.basket_id AND f3.fruit='orange')=1;
I have tested the query on your example. Demo
Upvotes: 0
Reputation: 4620
Please note for the example table, I added one more basket which is basket_id = 4, that has two apples only, and it will be a strong test sample for the query.
WITH ABC --sample table
AS
(
SELECT 1 as basket_id, 'Apple' as fruit
UNION ALL
SELECT 1 as basket_id, 'Orange' as fruit
UNION ALL
SELECT 1 as basket_id, 'Pear' as fruit
UNION ALL
SELECT 2 as basket_id, 'Apple' as fruit
UNION ALL
SELECT 2 as basket_id, 'Orange' as fruit
UNION ALL
SELECT 3 as basket_id, 'Apple' as fruit
UNION ALL
SELECT 3 as basket_id, 'Pear' as fruit
UNION ALL
SELECT 4 as basket_id, 'Apple' as fruit
UNION ALL
SELECT 4 as basket_id, 'Apple' as fruit
)
--main query:
SELECT basket_id FROM
(
SELECT *,CASE WHEN fruit in ('Apple','Orange') THEN 1 ELSE 0 END AS row_check
FROM ABC
) as A
GROUP BY basket_id
HAVING COUNT(DISTINCT row_check) =1 -- make sure there is no other fruit
AND COUNT(DISTINCT fruit) >1 -- make sure there are at least one apple and one orange
output: basket_id 2
Upvotes: 2
Reputation: 1277
select
f.basket_id,
(select count(1) from fruits where basket_id = f.basket_id) as fruits_in_basket,
(select count(1) from fruits where basket_id = f.basket_id and fruit in ("apple", "orange")) as specific_fruits_in_basket
from
fruits as f
group by f.basket_id
having fruits_in_basket = specific_fruits_in_basket
Here is a fiddle: http://sqlfiddle.com/#!9/f4ae3c/37/0
Upvotes: 1
Reputation: 2943
SELECT DISTINCT(basket_id)
FROM basket
where fruit IN ('apple', 'orange');
Upvotes: -1