2010-02-26 2 views
1

Мне нужна помощь в запросе MySQL, который я пытаюсь настроить. Мне нужно найти записи, соответствующие условиям, которые расположены в двух разных таблицах со многими отношениями.Нужна помощь по поисковому запросу MySQL

Я использую три таблицы в этом запросе, первый содержит проекты, второй содержит темы, а третий связывает их вместе. Я хочу, чтобы в запросе находились проекты, связанные с темой, выбранной пользователем. Пользователи могут также выбрать несколько тем для выполнения поиска. В этом случае я хочу показать проекты, связанные с обоими темами, а не с ними. Это то, что я не могу понять, как это сделать. Я ожидал, что мне придется делать что-то подобное, но этот запрос не дает никаких результатов, пока есть проект, связанный с обоими темами в базе данных.

SELECT `projects`.* 
FROM `projects`, `topics`, `projects_topics` 
WHERE (`name` LIKE '%%' || `vision` LIKE '%%' || `highlights` LIKE '%%' || `optional` LIKE '%%') 
    && ((`projects_topics`.`projects_id` = `projects`.`id` && `projects_topics`.`topics_id` = `topics`.`id` && `topics`.`id` = '1') 
     && (`projects_topics`.`projects_id` = `projects`.`id` && `projects_topics`.`topics_id` = `topics`.`id` && `topics`.`id` = '9')) 
ORDER BY `date_added` DESC 

Эти таблицы:

проекты

+--------------+--------------+------+-----+---------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+--------------+--------------+------+-----+---------+----------------+ 
| id   | int(11)  | NO | PRI | NULL | auto_increment | 
| fields_id | int(11)  | NO | PRI | NULL |    | 
| name   | varchar(255) | YES |  | NULL |    | 
| address  | varchar(255) | YES |  | NULL |    | 
| zip   | varchar(255) | YES |  | NULL |    | 
| city   | varchar(255) | YES |  | NULL |    | 
| state  | varchar(255) | YES |  | NULL |    | 
| countries_id | int(11)  | NO | PRI | NULL |    | 
| website  | varchar(255) | YES |  | NULL |    | 
| client  | varchar(255) | YES |  | NULL |    | 
| finished  | date   | YES |  | NULL |    | 
| budget  | int(11)  | YES |  | NULL |    | 
| vision  | text   | YES |  | NULL |    | 
| highlights | text   | YES |  | NULL |    | 
| innovation | text   | YES |  | NULL |    | 
| optional  | text   | YES |  | NULL |    | 
| publish  | tinyint(1) | YES |  | NULL |    | 
| date   | datetime  | YES |  | NULL |    | 
| featured  | tinyint(1) | YES |  | NULL |    | 
| frontpage | tinyint(1) | YES |  | NULL |    | 
| date_added | datetime  | YES |  | NULL |    | 
+--------------+--------------+------+-----+---------+----------------+ 

темы

+-------+--------------+------+-----+---------+----------------+ 
| Field | Type   | Null | Key | Default | Extra   | 
+-------+--------------+------+-----+---------+----------------+ 
| id | int(11)  | NO | PRI | NULL | auto_increment | 
| topic | varchar(255) | YES |  | NULL |    | 
| order | int(11)  | YES |  | NULL |    | 
+-------+--------------+------+-----+---------+----------------+ 

projects_topics

+-------------+---------+------+-----+---------+-------+ 
| Field  | Type | Null | Key | Default | Extra | 
+-------------+---------+------+-----+---------+-------+ 
| projects_id | int(11) | NO | PRI | NULL |  | 
| topics_id | int(11) | NO | PRI | NULL |  | 
+-------------+---------+------+-----+---------+-------+ 

ответ

1
SELECT p.* 
FROM (
     SELECT project_id 
     FROM project_topics pt 
     WHERE topics_id IN (5, 9) 
     GROUP BY 
       project_id 
     HAVING COUNT(*) = 2 
     ) pto 
JOIN projects p 
ON  p.project_id = pto.project_id 

или

SELECT p.* 
FROM projects p 
WHERE EXISTS 
     (
     SELECT NULL 
     FROM project_topics pt 
     WHERE pt.project_id = p.project_id 
       AND pt.topic_id IN (5, 9) 
     LIMIT 1 OFFSET 1 
     ) 

Убедитесь, что PK в project_topics определяется как (project_id, topic_id) (в таком порядке), или создать дополнительный UNIQUE индекс (topic_id, project_id) ,

+0

Позвольте мне убедиться, правильно ли я это понимаю. Например, если пользователи выбирают только одну тему, мне нужно установить OFFSET на 0. Если они выбирают 2 темы, мне нужно установить OFFSET на 1. Если выбрано 3 темы, мне нужно установить их равными 2 и так далее. Верный? – Abel

+0

@Abel: точно. – Quassnoi

Смежные вопросы