In a many to many relationship like these given tables:
1-pizza id, name
2-topping id, name
3-pizza_topping pid,tid (pid references pizza(id), tid references toppind (id))
I want to search for pizzas, depending on multiple not exactly named toppings. So all matches are dependent on user input and not exact. So he needs to say can say I want pizzas with all the topping not starting with 'q' and does not include mushroom.
In short, I will specify multiple patterns of names for the toppings I want. And the pizza must have all those toppings (Can't be just one of them). I have seen answers that use DISTINT, IN and HAVING COUNT , in many various forms like this Selecting an item matching multiple tags
and more. But this will not work because the strings supplied are supposed to be matched with 'LIKE' due to them possibly being a pattern, so I can't match with in.
And their count will not solve it (finding 'a%' will have different counts for each pizza, and when combined with other queries that can be equal. The count could be misleading because the 'a%' makes it match multiple times).
I've tried to auto formulate AND OR and NOT for the search condition given keyword and patterns for a query and translate them into this (This is not exactly the example above) :
SELECT p.* FROM Pizza p
JOIN PizzaToppping pt ON p.ID = pt.PizzaID
WHERE pt.ToppingID IN (SELECT ID FROM Toppings WHERE name LIKE 'a%')
AND pt.ToppingID NOT IN (SELECT ID FROM Toppings WHERE name LIKE 'mushroom')
AND pt.ToppingID IN (SELECT ID FROM Toppings WHERE name LIKE 'tuna%' OR name LIKE '%fish')
And I've tried using SELECT DISTINCT. But the issue is it seems to be getting the queries like a cross-product (which I partially understand but cant fix), and the DISTINCT eliminates repition but acts like a union of the set of results.
Is there a short way to write the query with the multiple patterns of words I'll search with. Or do I have to do something like this (I have not tested this, I don't know if it works correctly BTW):
SELECT p.* FROM Pizza p
JOIN PizzaToppping pt ON p.ID = pt.PizzaID
WHERE pt.ToppingID IN (SELECT ID FROM Toppings WHERE name LIKE 'a%')
INTERSECT
SELECT p.*
FROM Pizza p
JOIN PizzaToppping pt ON p.ID = pt.PizzaID
pt.ToppingID NOT IN (SELECT ID FROM Toppings WHERE name LIKE 'mushroom')
INTERSECT
SELECT p.*
FROM Pizza p
JOIN PizzaToppping pt ON p.ID = pt.PizzaID
pt.ToppingID IN (SELECT ID FROM Toppings WHERE name LIKE 'tuna%' OR name LIKE '%fish');
Note: I am using sqlite.
Also is there a more efficient way (if the intersection is the answer)?