Проблема с MySQL присоединиться - PullRequest
0 голосов
/ 07 июля 2011

У меня есть МНОГО-МНОГИЕ отношения между таблицами мастерских и категорий.

У меня есть 3 таблицы: мастерская, категория, категория_работы_ *. 1003 *

В категории_работа_класса у меня есть идентификаторы мастерской и категории.

category_workshop_tie:

category_id | workshop_id

Мастерская:

id | title

Категория:

id | name

И у меня есть код:

$this->db->query('
    SELECT workshop.*, tie.category_id 
    FROM `prefix_workshop` workshop, `prefix_category_workshop_tie` tie
    WHERE ((workshop.title LIKE ? OR workshop.descr LIKE ?) AND workshop.city LIKE ? AND workshop.state LIKE ?) AND (workshop.id = tie.workshop_id)
    ORDER BY `d_course`', '%'.($d['f'] ? $d['f'] : '' ).'%', '%'.($d['f'] ? $d['f'] : '' ).'%', '%'.($d['city'] != '0' ? str_replace('_', ' ', $d['city']) : '').'%', '%'.($d['state'] != '0' ? str_replace('_', ' ', $d['state']) : '').'%');

$ d равно $ _GET;
QUERY STRING: f = & city = Odessa & state = Odesska_Region & category = 0 & workshop_search_submit = Submit Пример вывода:

Array ( [id] => 11 [title] => Hello worldicos [presenter] => Bill [hours] => 5.00 [d_course] => 2011-07-06 [d_course_end] => 0000-00-00 [location] => [city] => Odessa [state] => Odesska Region [cost] => 53.00 [descr] => dwqhhd whqdhwq yhhd qywhdy hyqh d [sponsor] => Microshka [contact] => Mirgorod [website] => http://mirgorod.us [dt_update] => 2011-07-07 08:44:15 [user_id] => 1 [addr] => Kominterna street 10 A [image] => [category_id] => 6 ) Array ( [id] => 11 [title] => Hello worldicos [presenter] => Bill [hours] => 5.00 [d_course] => 2011-07-06 [d_course_end] => 0000-00-00 [location] => [city] => Odessa [state] => Odesska Region [cost] => 53.00 [descr] => dwqhhd whqdhwq yhhd qywhdy hyqh d [sponsor] => Microshka [contact] => Mirgorod [website] => http://mirgorod.us [dt_update] => 2011-07-07 08:44:15 [user_id] => 1 [addr] => Kominterna street 10 A [image] => [category_id] => 9 ) Array ( [id] => 11 [title] => Hello worldicos [presenter] => Bill [hours] => 5.00 [d_course] => 2011-07-06 [d_course_end] => 0000-00-00 [location] => [city] => Odessa [state] => Odesska Region [cost] => 53.00 [descr] => dwqhhd whqdhwq yhhd qywhdy hyqh d [sponsor] => Microshka [contact] => Mirgorod [website] => http://mirgorod.us [dt_update] => 2011-07-07 08:44:15 [user_id] => 1 [addr] => Kominterna street 10 A [image] => [category_id] => 17 ) Array ( [id] => 11 [title] => Hello worldicos [presenter] => Bill [hours] => 5.00 [d_course] => 2011-07-06 [d_course_end] => 0000-00-00 [location] => [city] => Odessa [state] => Odesska Region [cost] => 53.00 [descr] => dwqhhd whqdhwq yhhd qywhdy hyqh d [sponsor] => Microshka [contact] => Mirgorod [website] => http://mirgorod.us [dt_update] => 2011-07-07 08:44:15 [user_id] => 1 [addr] => Kominterna street 10 A [image] => [category_id] => 1 ) Array ( [id] => 11 [title] => Hello worldicos [presenter] => Bill [hours] => 5.00 [d_course] => 2011-07-06 [d_course_end] => 0000-00-00 [location] => [city] => Odessa [state] => Odesska Region [cost] => 53.00 [descr] => dwqhhd whqdhwq yhhd qywhdy hyqh d [sponsor] => Microshka [contact] => Mirgorod [website] => http://mirgorod.us [dt_update] => 2011-07-07 08:44:15 [user_id] => 1 [addr] => Kominterna street 10 A [image] => [category_id] => 4 ) Array ( [id] => 11 [title] => Hello worldicos [presenter] => Bill [hours] => 5.00 [d_course] => 2011-07-06 [d_course_end] => 0000-00-00 [location] => [city] => Odessa [state] => Odesska Region [cost] => 53.00 [descr] => dwqhhd whqdhwq yhhd qywhdy hyqh d [sponsor] => Microshka [contact] => Mirgorod [website] => http://mirgorod.us [dt_update] => 2011-07-07 08:44:15 [user_id] => 1 [addr] => Kominterna street 10 A [image] => [category_id] => 5 ) Array ( [id] => 11 [title] => Hello worldicos [presenter] => Bill [hours] => 5.00 [d_course] => 2011-07-06 [d_course_end] => 0000-00-00 [location] => [city] => Odessa [state] => Odesska Region [cost] => 53.00 [descr] => dwqhhd whqdhwq yhhd qywhdy hyqh d [sponsor] => Microshka [contact] => Mirgorod [website] => http://mirgorod.us [dt_update] => 2011-07-07 08:44:15 [user_id] => 1 [addr] => Kominterna street 10 A [image] => [category_id] => 7 ) Array ( [id] => 11 [title] => Hello worldicos [presenter] => Bill [hours] => 5.00 [d_course] => 2011-07-06 [d_course_end] => 0000-00-00 [location] => [city] => Odessa [state] => Odesska Region [cost] => 53.00 [descr] => dwqhhd whqdhwq yhhd qywhdy hyqh d [sponsor] => Microshka [contact] => Mirgorod [website] => http://mirgorod.us [dt_update] => 2011-07-07 08:44:15 [user_id] => 1 [addr] => Kominterna street 10 A [image] => [category_id] => 8 ) Array ( [id] => 11 [title] => Hello worldicos [presenter] => Bill [hours] => 5.00 [d_course] => 2011-07-06 [d_course_end] => 0000-00-00 [location] => [city] => Odessa [state] => Odesska Region [cost] => 53.00 [descr] => dwqhhd whqdhwq yhhd qywhdy hyqh d [sponsor] => Microshka [contact] => Mirgorod [website] => http://mirgorod.us [dt_update] => 2011-07-07 08:44:15 [user_id] => 1 [addr] => Kominterna street 10 A [image] => [category_id] => 13 )

Я печатаю _r'ed каждую строку.

Проблема в том, что я получаю из этого запроса: (workshop_matched_item) * все категории этого семинара.

Например: если один мастер-класс совпадает и этот семинар имеет 5 категорий, я получаю 5 строк.Но мне нужен 1 ряд с 5 категориями этого семинара.

Что я делаю не так?

Ответы [ 2 ]

2 голосов
/ 07 июля 2011

Группировка по workshop.id и использование функции GROUP_CONCAT() для tie.category_id:

SELECT workshop.*, GROUP_CONCAT(tie.category_id) AS category_id 
FROM `prefix_workshop` workshop, `prefix_category_workshop_tie` tie
WHERE ( (workshop.title LIKE ? OR workshop.descr LIKE ?)
  AND   workshop.city LIKE ? AND workshop.state LIKE ?)
  AND (workshop.id = tie.workshop_id)
GROUP BY workshop.id
ORDER BY ...

Подробнее о функции GROUP_CONCAT() см. В документации MySQL.например, если вы хотите использовать другой разделитель, а не запятую, или вы хотите определить порядок category_id s в списке.


Примечание. Синтаксис WHERE, который вы используете для присоединения кдве таблицы очень старые.Попробуйте вместо этого использовать явное JOIN:

SELECT workshop.*, GROUP_CONCAT(tie.category_id) AS category_id 
FROM `prefix_workshop` workshop
  JOIN `prefix_category_workshop_tie` tie
    ON workshop.id = tie.workshop_id
WHERE (workshop.title LIKE ? OR workshop.descr LIKE ?)
  AND workshop.city LIKE ?
  AND workshop.state LIKE ?
GROUP BY workshop.id
ORDER BY ...

Помимо того, что условия JOIN расположены рядом с таблицами JOINed и отделены от других условий WHERE, это полезно, поскольку во многих ситуациях (например, в этой)Строка из одной таблицы (мастерская) может вообще не относиться к какой-либо строке во второй таблице (категории).Эти семинары не будут показаны с кодом, который у вас есть (и ни одним из приведенных выше примеров JOIN).

Но вы все равно можете их показать.С синтаксисом WHERE все становится сложнее.С синтаксисом JOIN вы просто меняете JOIN на LEFT JOIN (поэтому включены ВСЕ столбцы из таблицы LEFT в отношении workshop LEFT JOIN tie, а не только связанные).

1 голос
/ 07 июля 2011

До сих пор не совсем ясно, в каком формате вы хотите получать результаты.

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

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

SELECT category_id
FROM prefix_category_workshop_tie
WHERE workshop_id = $workshopId

Если вы собираетесь использовать идентификаторы категорий для запроса таблицы категорий, вам не нужно хранить промежуточные идентификаторы, вы можете сделать что-то вроде:

SELECT category_id category.somevalue
FROM category_workshop_tie
  WHERE workshop_id = $workshopId
LEFT JOIN category
  ON category.id = category_id

Оба из них предполагают, что $workshopId был установлен из первого запроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...