Поиск MySQL с соединениями и сопоставлением

У меня есть одна таблица, заполненная информацией о компаниях (tblforetag) в Швеции, одна таблица с провинциями (tbllan) и одна таблица с городами (tblstad). Города связаны с провинциями с помощью идентификационных номеров, а в таблице компаний есть столбец с названием города (varchar).

Как найти все компании в одной провинции?

Я возился с соединениями, но не заставил его работать. У меня есть этот код прямо сейчас, который работает, но он будет искать только названия компаний и города (в таблице компаний):

$sql = "
    SELECT *, 
    MATCH(tblforetag.foretag) AGAINST(:keywords) AS kr
    FROM tblforetag
    WHERE MATCH(tblforetag.foretag) AGAINST(:keywords)
    ";
$sql .= $locisset ? "AND tblforetag.stad LIKE :location" : "";
$sql .= " LIMIT $offset, $rpp"; 
$query = $conn->Prepare($sql);
$query->BindValue(':keywords', $keywords);
if($locisset) $query->BindValue(':location', "%$location%");
$query->Execute();

person Christian Lundahl    schedule 17.01.2013    source источник
comment
$locisset — это логическая переменная, сообщающая мне, задан ли критерий местоположения или нет.   -  person Christian Lundahl    schedule 17.01.2013


Ответы (2)


Я не знаю структуру вашей таблицы, но что-то в этом роде должно помочь:

SELECT FROM companies 
LEFT JOIN cities ON (companies.city_id = cities.id)
LEFT JOIN regions ON (cities.region_id = regions.id)
WHERE region.name = 'your region'

Это даст вам компании в этом конкретном регионе.

person Andresch Serj    schedule 17.01.2013
comment
Это то, что я пробовал, но это всегда дает мне ВСЕ компании или вообще не соответствует. Я собираюсь изучить это еще раз. - person Christian Lundahl; 17.01.2013
comment
В вашем результате у вас также должно быть поле region.name. Из-за синтаксиса SQL записи с именем region.name, отличным от «вашего региона», не подходят и, следовательно, не могут быть в результате. Может быть, ваши отношения не работают? - person Andresch Serj; 17.01.2013
comment
Я не уверен, что понимаю тебя здесь. Конечно, я заменил «ваш регион» на что-то подходящее. Вот что у меня сейчас: SELECT *, MATCH(tblforetag.foretag) AGAINST(:keywords) AS kr FROM tblforetag LEFT JOIN tblstad ON tblforetag.stad = tblstad.Stad LEFT JOIN tbllan ON tbllan.Id = tblstad.Lan_id WHERE MATCH(tblforetag.foretag) AGAINST(:keywords) AND (tblforetag.stad LIKE :location OR tbllan.Lan LIKE :location) Ничего не возвращает. - person Christian Lundahl; 17.01.2013
comment
Просто в целях тестирования попробуйте исключить из этого ПОИСКПОЗ и использовать простой синтаксис WHERE tbllan.Lan LIKE :location. Просто чтобы убедиться, что ваши JOINS верны. - person Andresch Serj; 21.01.2013
comment
Я нашел проблему. Таблицы почему-то имели разную сортировку по умолчанию и поэтому не давали никаких результатов. На самом деле, он выдал ошибку, которую я не пробовал/не ловил. - person Christian Lundahl; 24.01.2013
comment
@Perplexor Рассмотрите возможность принятия одного из двух ответов или запросите дополнительную информацию. Это предотвратит привлечение большего внимания к этому Вопросу, а также покажет, по крайней мере, некоторую признательность людям, которые нашли время, чтобы помочь вам. - person Andresch Serj; 29.04.2014

Я думаю, было бы лучше заменить столбец city_name в таблице компаний на city_id.

SELECT a.*, p.provincename
FROM   companies a, cities c, provinces p
WHERE a.city_name = c.city_name
AND      c.city_id = p.city_id
AND      p.province_id = 5 // give your province id here
person cartina    schedule 17.01.2013
comment
Я знаю об этом, но эта база данных содержит повторно используемые данные и содержит более миллиона строк. Это невыполнимо. - person Christian Lundahl; 17.01.2013
comment
@Perplexor хорошо. Что насчет запроса? - person cartina; 17.01.2013
comment
Я переписал запрос, чтобы он соответствовал моим таблицам и полям ввода, например так: ПРОТИВ(:ключевые слова) И (tblforetag.stad LIKE :location ИЛИ (tblforetag.stad = tblstad.Stad AND tblstad.Lan_id = tbllan.Id AND tbllan.Lan = :location)) Но это по-прежнему не дает результатов. - person Christian Lundahl; 17.01.2013