Многоуровневый запрос MySQL? - PullRequest
3 голосов
/ 21 февраля 2010

У меня есть две таблицы (записи и теги) с таблицей ссылок «многие ко многим». Сейчас я делаю запрос для получения всех записей, соответствующих моим критериям, и запрос для каждой записи для получения тегов.

Можно ли сказать, что теги возвращаются через новый столбец в виде массива в первом запросе?

Ответы [ 2 ]

1 голос
/ 21 февраля 2010

Этот запрос:

SELECT     e.id                               entry_id
,          GROUP_CONCAT(t.txt ORDER BY t.txt) tags
FROM       entry e
LEFT JOIN  entry_tag et
ON         e.id = et.entry_id
LEFT JOIN  tag t
ON         et.tag_id = t.id
GROUP BY   e.id

Вернет теги в виде списка через запятую. Вы можете прочитать о GROUP_CONCAT для получения дополнительных опций: http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html#function_group-concat

В вашем приложении вы сможете легко развернуть это в массив. Например, в php вы можете использовать explode: http://php.net/manual/en/function.explode.php

Если вам нужно больше атрибутов из таблиц tag или entry_tag, вы можете добавить еще больше столбцов GROUP_CONCAT или придумать какой-нибудь формат сериализации для ваших данных (например, JSON) и использовать для этого GROUP_CONCAT или вы можете просто вернуть несколько строк для каждой записи и обработать результаты в приложении, чтобы сохранить теги вместе с записями:

$sql = '
    SELECT     e.id                  entry_id
    ,          t.id                  tag_id
    ,          t.txt                 tag_text
    ,          t.published           tag_published
    FROM       entry e
    LEFT JOIN  entry_tag et
    ON         e.id = et.entry_id
    LEFT JOIN  tag t
    ON         et.tag_id = t.id
    ORDER BY   e.id
';        
$result = mysql_query($ql);
$entry_id = NULL;
$entry_rows = NULL;
while ($row = mysql_fetch_assoc($result)) {
    if ($entry_id != $row['entry_id']) {
        if (isset($entry_id)) {           //ok, found new entry
            process_entry($entry_rows);   //process the rows collected so far
        }
        $entry_id = $row['entry_id'];
        $entry_rows = array();
    }
    $entry_rows[] = $row;                 //store row for his entry for later processing
}
if (isset($entry_id)){                    //process the batch of rows for the last entry
    process_entry($entry_rows);           
}
0 голосов
/ 21 февраля 2010

Вы можете использовать функции GROUP BY и GROUP_CONCAT, чтобы получить все теги одновременно в виде объединенной строки. http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html

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