Php 在多个表上使用一对多构造MySQL查询时遇到问题

Php 在多个表上使用一对多构造MySQL查询时遇到问题,php,activerecord,codeigniter,mysql,Php,Activerecord,Codeigniter,Mysql,我有一个博客风格的应用程序,允许用户用主题标记每篇文章。我将这些数据保存在三个单独的表中:实际博客帖子的帖子、各种标记的主题和posts\u topics一个存储两者之间关系的表 为了保持MVC结构尽可能干净,我使用Codeigniter,我想运行一个MySQL查询,它获取所有post数据和相关主题数据,并将其返回到一个数组或对象中。到目前为止,我一点运气都没有 表结构如下所示: Posts +--------+---------------+------------+-----------+-

我有一个博客风格的应用程序,允许用户用主题标记每篇文章。我将这些数据保存在三个单独的表中:实际博客帖子的帖子、各种标记的主题和posts\u topics一个存储两者之间关系的表

为了保持MVC结构尽可能干净,我使用Codeigniter,我想运行一个MySQL查询,它获取所有post数据和相关主题数据,并将其返回到一个数组或对象中。到目前为止,我一点运气都没有

表结构如下所示:

Posts
+--------+---------------+------------+-----------+--------------+---------------+
|post_id | post_user_id  | post_title | post_body | post_created | post_modified |
+--------+---------------+------------+-----------+--------------+---------------+
|     1  |    1          | Post 1     |  Body 1   |  00-00-00    |  00-00-00     |
|     2  |    1          | Post 1     |  Body 1   |  00-00-00    |  00-00-00     |
+--------+---------------+------------+-----------+--------------+---------------+

// this table governs relationships between posts and topics
Posts_topics
+--------------+---------------------+-------------------------+-----------------+
|post_topic_id | post_topic_post_id  | post_topic_topic_id | post_topic_created  | 
+--------------+---------------------+-------------------------+-----------------+
|     1        |    1                | 1                   |         00-00-00    |  
|     2        |    1                | 2                   |         00-00-00    |
|     3        |    2                | 2                   |         00-00-00    |  
|     4        |    2                | 3                   |         00-00-00    |   
+--------------+---------------------+-------------------------+-----------------+

Topics
+---------+-------------+-----------+----------------+
|topic_id | topic_name  | topic_num | topic_modified |
+---------+-------------+-----------+----------------+
|     1   |  Politics   | 1         | 00-00-00       |
|     2   |  Religion   | 2         | 00-00-00       |
|     3   |  Sports     | 1         | 00-00-00       |
+---------+-------------+-----------+----------------+
我尝试了这个简单的查询,并获得了n次成功:

select * from posts as p inner join posts_topics as pt on pt.post_topic_post_id = post_id join topics as t on t.topic_id = pt.post_topic_topic id
我也尝试过使用GROUP_CONCAT,但这给了我两个问题:1我需要主题中的所有字段,而不仅仅是名称;2我的MySQL中有一个小故障,所以所有GROUP_CONCAT数据都以BLOB形式返回,请参见

我也乐于听到任何建议,我运行两个查询并尝试为每个结果构建一个数组;我用下面的代码尝试了这一点,但失败了。这段代码还包括加入用户表,这也很好地保留了这一点:

    $this->db->select('u.username,u.id,s.*');
    $this->db->from('posts as p');
    $this->db->join('users as u', 'u.id = s.post_user_id');
    $this->db->order_by('post_modified', 'desc');
    $query = $this->db->get();
    if($query->num_rows() > 0)
    {
        $posts = $query->result_array();
        foreach($posts as $p)
        {
            $this->db->from('posts_topics as p');
            $this->db->join('topics as t','t.topic_id = p.post_topic_topic_id');
            $this->db->where('p.post_topic_post_id',$p['post_id']);
            $this->db->order_by('t.topic_name','asc');
            $query = $this->db->get();
            if($query->num_rows() > 0)
            {
                foreach($query->result_array() as $t)
                {
                    $p['topics'][$t['topic_name']] = $t;
                }
            } 
        }
        return $posts;
    }

非常感谢您的帮助。

这个查询应该可以解决这个问题。只需将*更改为所需的字段列表,这样就不会在每次运行查询时提取过多的数据

Select
  *
FROM
  posts,
  post_topics,
  topics
WHERE
  post_topic_topic_id = topic_id AND
  post_topic_post_id = post_id
 ORDER BY
 post_id, topic_id;

Select
  *
FROM
  posts,
  post_topics,
  topics,
  users
WHERE
  post_topic_topic_id = topic_id AND
  post_topic_post_id = post_id AND
  post_user_id = user_id
 ORDER BY
 post_id, topic_id;

天哪,你能行!看到它有助于帮助。不知道,试试这个 选择 邮政编码, 组\u CONCATDISTINCT主题\u名称作为名称 从…起 帖子, 发布主题, 话题 哪里 post\u topic\u topic\u id=主题id和 帖子主题帖子id=帖子id

分组 邮政编码

你得到 1.“政治、宗教”
2,“体育,宗教”

谢谢你的回答,但这给了我每篇文章的多个结果——与文章相关的每个主题一个结果。我需要它只返回一次实际的帖子,然后返回与帖子相关的所有主题$myArray=数组$rs=mysql\u fetch\u assoc$q$last_post_id=$rs['post_id']$主题=;do{if$last_post_id!=$rs['post_id']{$myArray[]=array$last_post_id=>$topics;$topics=;$last_post_id=$rs['post_id']}$topics.=$rs['topic name'].}而$rs=mysql_fetch assoc$q;由于某种原因,我在构建数组时遇到了一些困难,但最终还是成功了。谢谢你的建议。你说得对,Group_Concat会给我主题的名称,但在这种情况下,我想从topics表中获取更多数据,所以我在你的第一个答案中遵循了建议。你可以将Group_Concat查询用作返回所需额外数据的子查询。选择*,选择GROUP_CONCATDISTINCT topic_name作为来自帖子的名称,post_topic,其中post_topic_topic_id=topic_id和post_topic_post_id=post_id作为来自帖子的主题,其中user_id=post_user_id的用户;