У меня три таблицы: posts
, post_tags
и tags
. У одного сообщения может быть много тегов, и один тег может принадлежать многим сообщениям. Из-за этого отношения «многие ко многим» я сделал таблицу post_tags
. Он имеет два поля: p_id
и t_id
. Они оба являются внешними ключами таблицы столбов и таблиц соответственно. Теперь, когда я запускаю свой PHP-метод для получения последних сообщений, я хочу также получить теги, принадлежащие этому сообщению, в одном запросе. Для справки, вот эти три таблицы:
сообщений
| 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 |
теги
| t_id | name | slug | ------------------------------------ | 3 | programming | programming |
Вот код PHP, который я использую сейчас, чтобы получать последние сообщения без тегов:
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; }
Как я могу адаптировать мой запрос, чтобы получить имя и пул тегов, принадлежащих каждому сообщению?
Спасибо за любую помощь!
Неявное соединение:
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
Явное соединение:
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
Обновляется, чтобы увидеть правильную, нормализованную схему базы данных за один раз.
Вы, вероятно, просто захотите создать их в отдельный массив, поскольку это много-ко-многим.
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; }