Какая жесть у вас написана.
Для начала то, что вы селектите подряд таблицы - это внутри mysql является inner join. Вам же нужен left join. Тогда, если записи в таблице нету товар все равно будет выбираться.
Дальше общий вид запроса будет таким:
SELECT t.* FROM tovar
LEFT JOIN svyazka1 as s1 ON (s1.id_from_tovar = t.id)
LEFT JOIN svyazka2 as s2 ON (s2.id_from_tovar = t.id)
/* .. еще join при необходимости.. */
WHERE
s1.category_id = 1 /* ID искомой категории внутри связки */
AND
s2.category_id = 2 /* ID искомой категории внутри связки */
но в этом запросе есть одно НО. Сюда не приджойнить названия категорий, по которым идет поиск (а нужно ли?). Тут два варианта.
- Отдельными мелкими запросами выбирать названия категорий для товара (не оч хорошо, но некритично, таблицы обычно маленькие со списком категорий).
- Создать дополнительное поле в таблице с товарами, в которой хранить "кеш" (json/serialized) списка категорий и их ID, чтобы быстро их вывести, не обращаясь в БД. В этом случае дополнительная сложность - при изменении таблицы категорий придется пересобирать кеш в таблице товаров. и вообще следить за его актуальностью