2013-03-11 72 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']; 
}