Reputation: 195
I am trying to write a query in MySQL with output in PHP, but it's proving rather difficult.
I have a table with 3 columns (yes I know the database layout for this isn't the best, but I can't change this, the client has other software using this db with this exact layout)
Amount - Product - Package
2 - Apple - Fruitbasket1
1 - Pear - Fruitbasket1
5 - Grape - Fruitbasket1
2 - Apple - Fruitbasket2
1 - Pear - Fruitbasket2
9 - Banana - Fruitbasket2
So far I came up with this:
SELECT package
FROM `data`
WHERE package IN
(
SELECT package
FROM `data`
WHERE product = 'apple' AND amount = '2'
)
AND package IN
(
SELECT package
FROM `data`
WHERE product = 'pear' AND amount ='1'
)
AND package IN
(
SELECT package
FROM `data`
WHERE product = 'grape' AND amount = '5'
)
LIMIT 0,1
The issue is that when the customer would fill out "apple" and "2" on the form, it would return all the baskets containing 2 apples. What I need is a statement that will only accept the exact products and their amounts to return the one basket those ingredients belong to, or nothing at all.
So even though 1 pear and 2 apples are in Fruitbasket1, it should not give Fruitbasket1 as a result if the other part, namely 5 grapes, are not specified by the customer.
Upvotes: 3
Views: 107
Reputation: 32392
this query will return all packages where the only product is 2 Apples
select package from `data`
group by package
having count(case when amount = 2 and product = 'Apple' then 1 end) = 1
and count(*) = 1
if you want 1 pear and 2 apples for example
select package from `data`
group by package
having count(
case
when (amount = 2 and product = 'Apple') or (amount = 1 and product = 'Pear')
then 1
end) = 2
and count(*) = 2
you could also write this as
select package from `data`
group by package
having count(case when amount = 2 and product = 'Apple' then 1 end) = 1
and count(case when amount = 1 and product = 'Pear' then 1 end) = 1
and count(*) = 2
Upvotes: 2
Reputation: 10865
I only have Oracle handy so you may have to adjust the syntax somewhat, but following your original style I've added a "not in" section to make sure the basket contains only the fruits you are looking for. Here are some inserts with a couple of examples:
create table data (amount integer, product varchar(12), package varchar(16));
insert into data values (2, 'Apple', 'Fruitbasket1');
insert into data values (1, 'Pear', 'Fruitbasket1');
insert into data values (5, 'Grape', 'Fruitbasket1');
insert into data values (2, 'Apple', 'Fruitbasket2');
insert into data values (1, 'Pear', 'Fruitbasket2');
insert into data values (9, 'Banana', 'Fruitbasket2');
insert into data values (2, 'Apple', 'Fruitbasket3');
insert into data values (2, 'Apple', 'Fruitbasket4');
insert into data values (1, 'Pear', 'Fruitbasket4');
SELECT package
FROM data
WHERE package IN
(
SELECT package
from data
WHERE product = 'Apple' AND amount = '2'
)
and package not in
(
SELECT package
from data
WHERE product <> 'Apple'
)
group by package
;
SELECT package
FROM data
WHERE package IN
(
SELECT package
from data
WHERE product = 'Apple' AND amount = '2'
)
AND package IN
(
SELECT package
FROM data
WHERE product = 'Pear' AND amount ='1'
)
and package not in
(
SELECT package
from data
WHERE product <> 'Apple' and product <> 'Pear'
)
group by package
;
Upvotes: 2