2010-01-15 4 views
1

Я пытаюсь создать эффективный запрос, который будет извлекать «проекты» из базы данных и все соответствующие «теги», которые были назначены этому конкретному проекту.MySQL 3 таблицы в одном запросе?

Мои настройки таблицы подражает из WordPress, и это немного сложнее:

term 
- Where I define the tags name, slug etc 

term_relationships 
- Links the project to a term in the above table. 

term_taxonomy 
- Defines the taxonomy of each of terms in the term table e.g. 'category', 'tag'. 

Итак, что мне нужно сделать, это первый запрос к таблице term_taxonomy для всех записей с систематики «тега», затем процеживают эти результаты позволяют возвращать только термины, указанные в term_relationships. Наконец, мне нужно запросить таблицу терминов, чтобы вернуть соответствующие теги.

Мой вопрос - это самый быстрый способ сделать это? Я думаю, было бы лучше разбить его на несколько запросов, например. Запрос 1: получение проекта, запрос 2: получение тегов проекта, но, пожалуйста, подумайте, что у меня может быть до 20-30 проектов на страницу.

PS: Я знаю, что было бы намного проще создать новый стол специально для тегов, но сейчас я хочу ограничить его текущей настройкой.

Любая помощь была бы высоко оценена, так как это сводит меня с ума!

ответ

2
select  p.id 
,   p.name 
,   group_concat(t.text order by t.text) as tags 
from  project    p 
left join term_relationships tr 
on   p.id    = tr.project_id 
left join term     t 
on   tr.term_id   = t.id 
left join term_taxonomy  tt 
on   t.term_taxonomy_id = tt.id 
and  'tag'    = tt.type 
group by p.id 

отмечает, что положение group by не включает в себя все выбранные столбцы из проекта - другие базы данных будут суки об этом, но Msql не будут. Также обратите внимание, что в этом случае вполне справедливо, поскольку p.id является основным ключом проекта, поэтому может быть только одно отличное значение name за p.id.

Одно слово предостережения RE GROUP_CONCAT():

Результат усекается до максимальной длины, которая задается group_concat_max_len системной переменной, которая имеет значение по умолчанию 1024. Значение может быть установлено выше, хотя эффективная максимальная длина возвращаемого значения ограничена значением max_allowed_packet. Синтаксис для изменения значения group_concat_max_len во время выполнения следующий: где val - целое число без знака:

SET [GLOBAL | СЕССИЯ] group_concat_max_len = val;

См http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat

Так заранее решить, насколько большой список тегов может быть, и установить @@ group_concat_max_len к этому значению.

+0

Спасибо, я никогда не знал о функции group_concat, это здорово! Единственная проблема здесь в том, что мне также нужно получить slug для каждого тега, а также имя. Есть ли в любом случае, чтобы получить два столбца из таблицы терминов, а не только имя? – Hanpan

+1

Ханпан, да. Вы можете либо написать второе выражение GROUP_CONCAT, либо использовать свой язык (php?), Чтобы взорвать их в массивы, или вы можете написать какое-то выражение для непосредственного комбинирования тегов и slug. Вы могли бы даже написать: «GROUP_CONCAT ('', text, '« ORDER BY text »), но лично я бы этого не делал - я чувствую, что его лучше решить в php и использовать базу данных только для извлечения данных. Одно слово осторожности. Поскольку вы новичок в 'GROUP_CONCAT', я должен указать, что он обрезает результат, если результат длиннее, чем' group_concat_max_len'. См. Мой отредактированный ответ для получения более подробной информации. –

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