SQL - 多对多 - 如何在一个查询中执行?

时间:2013-03-11 04:25:36

标签: php mysql sql join subquery

如果我有一个这样的数据库有3个表:

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 个答案:

答案 0 :(得分: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列(或使用您自己的SEPARATORGROUP_CONCAT

第二个与上面类似,但你自己进行聚合。否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'];
}