开发者

Multi-tiered MySQL query?

I have two tables(entries and tags) with a many-to-many linking table. Right now, I'm making a query to retrieve all the entries that meet my cri开发者_开发问答teria, and a query for each entry to retrieve the tags.

Would there be a way to say, have the tags returned through a new column as an array in the first query?


This query:

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

Will return the tags as a comma-separated list. You can read up on GROUP_CONCAT for more options: http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html#function_group-concat

In your app you should be able to expand this into an array quite easily. For example in php, you could use explode: http://php.net/manual/en/function.explode.php

If you need more attributes from the tag or entry_tag tables, you can either add yet more GROUP_CONCAT columns, or think of some serialization format for your data (like JSON) and use GROUP_CONCAT on that, or you can simply return multiple rows per entry and process the results in the application to keep tags together with entries:

$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);           
}


You can use GROUP BY and GROUP_CONCAT function to get all tags at once as a concatenated string. http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜