Retrieving tags based on post ID

六眼飞鱼酱① 提交于 2019-12-13 18:00:37

问题


I have three tables: posts, post_tags and tags. One post can have many tags, and one tag can belong to many posts. Because of that many-to-many relationship, I made a post_tags table. It has two fields: p_id and t_id. They're both foreign keys to the posts table and tags table respectively. Now, when I run my PHP method to get the latest posts, I want to also retrieve the tags belonging to that post in one query. Just for reference, here's those three tables:

posts

| p_id | c_id | u_id |   title   |     body    |      published      |
----------------------------------------------------------------------
|  1   |  1   |   1  | first post| lorem ipsum | 2012-01-27 18:37:47 |

post_tags

| p_id | t_id |
---------------
|  1   |  3   |

tags

| t_id |     name    |     slug    |
------------------------------------
|  3   | programming | programming |

Here's the PHP code I'm using now to get the latest posts without the tags:

public function getLatestPosts()
{
    $query = $this->db->query('SELECT title, clean_title, body, published FROM posts ORDER BY published DESC');
    $blogPosts = array();
    foreach ($query->result() as $row)
    {
        $blogPosts[] = array('title' => $row->title,
                             'clean_title' => $row->clean_title,
                             'body' => $row->body,
                             'published' => $row->published);
    }

    return $blogPosts;
}

How can I adapt my query to get the name and slug of the tags belonging to each post?

Thanks for any help!


回答1:


Implicit join:

SELECT title, clean_title, body, published, name, slug
FROM posts, posts_tags, tags
WHERE posts.p_id=posts_tags.p_id AND posts_tags.t_id=tags.t_id
ORDER BY published DESC

Explicit join:

SELECT title, clean_title, body, published, name, slug
FROM posts
LEFT JOIN posts_tags ON posts.p_id=posts_tags.p_id
LEFT JOIN tags ON posts_tags.t_id=tags.t_id
ORDER BY published DESC

It's refreshing to see a correct, normalized database schema for once.




回答2:


You'll probably just want to build them out into a separate array since it's many-to-many.

public function getLatestPosts()
{
    $query = $this->db->query('SELECT p_id, title, clean_title, body, published FROM posts ORDER BY published DESC');
    $blogPosts = array();
    foreach ($query->result() as $row)
    {
        $blogPosts[] = array('title' => $row->title,
                             'clean_title' => $row->clean_title,
                             'body' => $row->body,
                             'published' => $row->published,
                             'tags' => $this->getPostTags($row->p_id);
    }
    return $blogPosts;
}

public function getPostTags($pid)
{
    $query = $this->db->query('SELECT name, slug FROM tags INNER JOIN post_tags on tags.t_id = post_tags.t_id WHERE post_tags.p_id = ' . $pid);
    $postTags = array();
    foreach ($query->result() as $row)
    {
        $postTags[] = array('name' => $row->name,
                             'slug' => $row->slug);
    }
    return $postTags;
}


来源:https://stackoverflow.com/questions/9047168/retrieving-tags-based-on-post-id

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!