使用SQL连接获取帖子标签

时间:2012-01-28 19:14:43

标签: php mysql sql database database-schema

我正在尝试在一个SQL查询中检索每篇博文的标记。我有一个posts表,post_tags表和一个tags表。存在post_tags表以删除帖子和标签之间的多对多关系。这是这些表的模式:

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


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


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

我正在使用的PHP方法:

public function getLatestPosts()
{
    $query = $this->db->query('SELECT title, clean_title, body, published, name, slug
                               FROM posts
                               LEFT JOIN post_tags ON posts.p_id=post_tags.p_id
                               LEFT JOIN tags ON post_tags.t_id=tags.t_id
                               ORDER BY published DESC');
    $posts = array();
    foreach ($query->result() as $row)
    {
        $posts[] = array('title' => $row->title,
                             'clean_title' => $row->clean_title,
                             'body' => $row->body,
                             'published' => $row->published,
                             'tags' => array('name' => $row->name,
                                             'slug' => $row->slug));
    }
    print_r($posts);
    return $posts;
}

它有点工作,每个帖子都会检索帖子标签,但我有重复的帖子。这是查询结果的print_r转储:

Array
(
    [0] => Array
        (
            [title] => Second blog post, this is a pretty long title
            [clean_title] => second-blog-post-this-is-a-pretty-long-title
            [body] => Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eget est sit amet libero volutpat eleifend facilisis sollicitudin nisl. Nulla elit eros, semper eget tincidunt quis, egestas a nisl. Duis tempor tempus sapien consequat pellentesque. Cras vitae orci risus. Duis urna velit, interdum ac consectetur nec, condimentum non tellus. Sed nec nibh nisi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras purus nulla, tincidunt quis placerat a, interdum at turpis. Pellentesque in lectus lacus. Sed at venenatis neque.
            [published] => 2012-01-27 20:15:52
            [tags] => Array
                (
                    [name] => 
                    [slug] => 
                )

        )

    [1] => Array
        (
            [title] => This is my first post!
            [clean_title] => this-is-my-first-post
            [body] => Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eget est sit amet libero volutpat eleifend facilisis sollicitudin nisl. Nulla elit eros, semper eget tincidunt quis, egestas a nisl. Duis tempor tempus sapien consequat pellentesque. Cras vitae orci risus. Duis urna velit, interdum ac consectetur nec, condimentum non tellus. Sed nec nibh nisi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras purus nulla, tincidunt quis placerat a, interdum at turpis. Pellentesque in lectus lacus. Sed at venenatis neque.
            [published] => 2012-01-27 18:37:47
            [tags] => Array
                (
                    [name] => programming
                    [slug] => programming
                )

        )

    [2] => Array
        (
            [title] => This is my first post!
            [clean_title] => this-is-my-first-post
            [body] => Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eget est sit amet libero volutpat eleifend facilisis sollicitudin nisl. Nulla elit eros, semper eget tincidunt quis, egestas a nisl. Duis tempor tempus sapien consequat pellentesque. Cras vitae orci risus. Duis urna velit, interdum ac consectetur nec, condimentum non tellus. Sed nec nibh nisi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras purus nulla, tincidunt quis placerat a, interdum at turpis. Pellentesque in lectus lacus. Sed at venenatis neque.
            [published] => 2012-01-27 18:37:47
            [tags] => Array
                (
                    [name] => android
                    [slug] => android
                )

        )

    [3] => Array
        (
            [title] => This is my first post!
            [clean_title] => this-is-my-first-post
            [body] => Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eget est sit amet libero volutpat eleifend facilisis sollicitudin nisl. Nulla elit eros, semper eget tincidunt quis, egestas a nisl. Duis tempor tempus sapien consequat pellentesque. Cras vitae orci risus. Duis urna velit, interdum ac consectetur nec, condimentum non tellus. Sed nec nibh nisi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras purus nulla, tincidunt quis placerat a, interdum at turpis. Pellentesque in lectus lacus. Sed at venenatis neque.
            [published] => 2012-01-27 18:37:47
            [tags] => Array
                (
                    [name] => windows
                    [slug] => windows
                )

        )

)

正如我所看到的,它不是返回帖子的每个标签,而是返回不同标签之外的一个帖子。我需要它,以便每个帖子的tags数组都有一个元素用于该帖子的每个标记。

非常感谢任何帮助:)

1 个答案:

答案 0 :(得分:0)

从SQL中检索数据后,

在PHP级别过滤数据:

public function getLatestPosts()
{
    $query = $this->db->query('SELECT p_id, title, clean_title, body, published, name, slug
                               FROM posts
                               LEFT JOIN post_tags ON posts.p_id=post_tags.p_id
                               LEFT JOIN tags ON post_tags.t_id=tags.t_id
                               ORDER BY published DESC');
    $posts = array();
    foreach ($query->result() as $row)
    {
        if (!isset($posts[$row->p_id])) {
            $posts[$row->p_id] = array('title' => $row->title,
                                       'clean_title' => $row->clean_title,
                                       'body' => $row->body,
                                       'published' => $row->published,
                                       'tags' => array());
        }
        $posts[$row->p_id]['tags'][] = array('name' => $row->name,
                                             'slug' => $row->slug);
    }
    print_r($posts);
    return $posts;
}