php - 在多个表上使用一对多构建 MySQL 查询时遇到问题

标签 php activerecord codeigniter mysql

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

为了保持 MVC 结构(我使用 Codeigniter)尽可能干净,我想运行一个 MySQL 查询来获取所有帖子数据和关联的主题数据,并将其返回到一个数组或对象中。到目前为止,我还没有任何运气。

表结构是这样的:

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       |
+---------+-------------+-----------+----------------+

我已经尝试了这个简单的查询,并取得了成功:

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(请参阅 here )。

我也愿意听取任何建议,我运行两个查询并尝试为每个结果构建一个数组;我尝试使用下面的代码但失败了(此代码还包括加入用户表,这也很好保留):

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

关于php - 在多个表上使用一对多构建 MySQL 查询时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3992426/

相关文章:

php - 使用ajax codeigniter php根据日期检索数据库值

php - 使用php从ms access db获取最大和最小时间

php - 调用未定义的方法 CI_DB_mysql_driver::num_rows()

php - MySQL中如何处理动态列计数

php - PHP 中的 RFC1123 和 RFC2822 日期时间格式有什么区别?

mysql - Rails 3 ORDER BY FIELD 和最后一个

php - CodeIgniter 事件记录,在 ->select() 函数中添加 IF 语句

sql - PG::InvalidColumnReference: 错误:对于 Ruby on Rails 应用程序中的 SELECT DISTINCT

php - 查询返回不存在的行

php - HTTP ://Becomes http%3A%2F%2F in CodeIgniter