2013-03-11 73 views
1

如果我有這樣的分貝與3個表:SQL - 多對多 - 如何做到這一點的一個查詢?

Table: BlogEntries 
BlogEntries.id (pk) 
BlogEntries.blogText 

Table: Tags 
Tags.id (pk) 
Tags.TagName 

Table: TagsForBlogEntries 
TagsForBlogEntries.id (pk) 
TagsForBlogEntries.tag_id 
TagsForBlogEntries.entry_id 

,如果我想獲得博客條目列表,並獲得這樣的數據(表示爲一個數組):

array (
[0] => array(
    [id] => '1', 
    [blogText] => 'example text', 
    [tags] => array(
     array([id]=>1, [TagName] => 'A Test Tag 1'), 
     array([id]=>2, [TagName] => 'A Test Tag 2'), 

    ) 
), 

(即與所有標籤)。如何做到這一點的最佳方式?

我目前會這樣(僞代碼) - 基本運行一個子查詢「手動」(而不是從原始的SQL查詢):

select * from BlogEntries; 
$rows =array(); 
foreach($blogEntries as $row) { 

    $row['tags'] = mysql_fetch_array(mysql_query("select * from Tags left join TagsForBlogEntries on TagsForBlogEntries.tag_id = tags.id where entry_id = " . $row['id'])) ; 
    $rows[] = $row; 

} 

回答

1

有一對夫婦的方式。一是組由博客文章:

SELECT be.id, blogText, GROUP_CONCAT(TagName) AS tags 
FROM BlogEntries be JOIN TagsForBlogEntries tbe ON (be.id = tbe.entry_id) 
JOIN Tags ON (tbe.tag_id = Tags.id) 
GROUP BY be.id 

當你遍歷每一行,可以拆分通過逗號tags柱(或GROUP_CONCAT使用自己的SEPARATOR

第二是相似。以上,但你自己做聚合。沒有GROUP BY

while ($row = $result->fetch()) { 
    if (!isset($blogs[$row['id']]) { 
     $blogs[$row['id']] = array(
      'text' => $row['blogText'], 
      'tags' => array() 
     ); 
    } 
    $blogs[$row['id']]['tags'] = $row['TagName']; 
}