If all you want is for the query to work, you should be able to use:
SELECT DISTINCT restaurant.*,branch.*
from restaurant,branch,restaurant_cuisines,restaurant_collections
WHERE restaurant.restaurant_id=branch.restaurant_id
AND restaurant_cuisines.cuisine_id IN (2,3)
AND restaurant_collections.collection_id IN (NULL);
But this will always return no results.
If you want something a little more flexible, or if you are expecting all results if collection_id
does not have any values passed to it, I recommend changing from implicit to explicit joins.
Right now you're using an implicit join syntax:
SELECT A.*, B.*, C.* FROM A,B,C
WHERE A.j=B.j AND A.j=C.j
The problem with this is that if C.j
is empty, even if you fix your syntax, your query will return nothing.
Explicit joins allow for a more nuanced approach:
SELECT A.*, B.*, C.* FROM A
INNER JOIN B ON A.j=B.j AND B.v IN (1,2)
LEFT JOIN C ON A.j=C.j AND C.v IN (NULL);
When you code, instead of passing an empty string, pass a null value (or, if you're not using prepared statements, pass a string containing NULL
). Otherwise, pass the values as a list.
If you need the rows to be ignored only when there are no values, you can do something like this instead:
SELECT A.*, B.*, C.* FROM A
INNER JOIN B ON A.j=B.j AND B.v IN (1,2)
LEFT JOIN C ON A.j=C.j
WHERE (COALESCE(<val>) IS NULL OR C.v IN (<val>));
When you add the LEFT JOIN
and then refer to it in the WHERE
clause, you can easily check if the C.v
contains the list of values, if the value passed is not null by using the COALESCE function.
- Scenario 1, there are values in , return only those values.
- Scenario 2, there are no values in and =NULL. Return everything.
In summary, LEFT
joins are very flexible and allow you to go back later and optionally enforce a strict INNER JOIN
. They should not be used when an INNER JOIN
does the job, but most definitely have their uses, such as here.
A note on LEFT
vs INNER
:
- If you want the query to execute even if the list is empty, use
LEFT JOIN
.
- If you want the query to return results only if there are values in the list, then use
INNER JOIN
.