2015-05-08 2 views
1

У меня есть таблица с двумя отношениями.SQL-поиск в отношениях

Структура данных и пример:

A/Employee 
id fields 
1 Mike Miller 
2 Lisa Miller 

B/Skill 
aid name 
1 SQL 
1 PHP 

C/Language 
aid name 
1 German 

мне нужен запрос, который показывает результаты от основной таблицы и поиска по ключевому слову в таблицах отношения.

Поиск Miller -> Майк Миллер, Лиза Миллер
Поиск SQL -> Mike Miller
Поиск Немецкий -> Майк Миллер

Есть 10.000 строк в основной таблице и 100.000 связи. Я пробовал его с JOIN, но запрос очень медленный.

Кроме того, те же строка из основной таблицы отображаются в целях несколько раз, когда Есть более одного соотношения для этой строки:

Поиск Miller
возвратов: Майк Миллер, Майк Миллер

(Mike Miller отображается более чем один раз)

SELECT fields 
FROM A 
JOIN B ON id = B.aid JOIN C ON id = C.aid 
WHERE fields LIKE '%"+$search+"%' OR B.name LIKE '%"+$search+"%' OR C.name LIKE '%"+$search+"%'" 

Я пытался исправить себе cond с DISTINCT, но теперь строки без отношений не отображаются.

Я хочу показать каждую строку из главного стола ровно один раз. Какой запрос мне нужен?

+0

Не могли бы вы привести пример вашего ожидаемого результата? –

+0

LIKE - это медленный поиск, поскольку индексы не используются. – jarlh

+0

LIKE может быть довольно медленным. Чтобы повысить эффективность, вы можете использовать MATCH с FULLTEXT INDEX. http://makandracards.com/makandra/12813-performance-analysis-of-mysql-s-fulltext-indexes-and-like-queries-for-full-text-search –

ответ

0

Проблема с первым запросом, так как вы говорите себе, что вы получите несколько повторяющихся строк вернулись. Не странно, так как я полагаю, что соотношение между таблицей А и таблицей В & С является один-ко-многим.

В следующей попытке вы добавили DISTINCT, и что на самом деле будет избавиться от дубликатов, но регулярные присоединиться (или внутреннее соединение) будет возвращать только матчи, где можно объединить данные, то есть, где данные существуют в оба соединенные таблицы.

Вводя LEFT JOIN:

SELECT DISTINCT fields 
FROM A 
LEFT JOIN B ON id = B.aid 
LEFT JOIN C ON id = C.aid 
WHERE fields LIKE '%"+$search+"%' OR B.name LIKE '%"+$search+"%' OR C.name LIKE '%"+$search+"%'" 

Это всегда будет искать все данные из таблицы А, а те из таблицы B & C, где присоединяется может быть сделано. DISTINCT гарантирует, что возвращаются только уникальные строки. Вы можете также использовать GROUP BY для того же результата, но это обычно используется для агрегированных методов.

0

LEFT JOIN.

Пример:

SELECT distinct e.empname FROM Employee e 
LEFT JOIN skill s ON s.aid = e.id 
LEFT JOIN lang l ON l.aid = e.id 
WHERE e.empname LIKE '%Miller%' OR s.name LIKE '%Miller%' OR l.name LIKE '%Miller%' 

Доказательства SQL Fiddle