我正在使用的博客有3个不同的表格。
第一张表:blog_posts,它有一个ID,标题,内容,user_id(创建帖子的人),created_date和slug。
第二张表:blog_tags,它有一个ID,post_id和tag_id
第3张表:标签,它有ID和标签
我使用表3保存所有标签一次,因此没有重复。然后我使用表2将标签连接到帖子(表1)。
我遇到的问题是从特定标签获取所有帖子,并返回所有其他标签。
我的代码现在只返回我想要查找帖子的标签,但我仍想写出其余的标签,只显示HAS的帖子包含该特定标签......
我通常对SQL很敏锐,但这次我的脑袋完全静止......请帮帮我:) 如果重要的话,我正在使用PHP和CodeIgniter。
提前致谢。
麦克
修改
我将结果打印为json,这给了我以下内容:
{
"data": [
{
"id": "28",
"title": "blabla",
"content": "<p>hello<\/p>",
"user_id": "1",
"created_date": "2014-08-18 23:57:22",
"slug": "blabla-2014-08-18-235722"
},
{
"id": "34",
"title": "test2",
"content": "<p>test2<\/p>",
"user_id": "1",
"created_date": "2014-08-23 21:41:00",
"slug": "test2-2014-08-23-214100"
}
],
"success": true
}
在下面的答案的帮助下。我的SQL和代码现在说:
$sql = "SELECT * FROM blog_posts bp
WHERE EXISTS(SELECT * FROM blog_tags bt INNER join
tags t ON t.id = bt.tag_id
WHERE bp.id = bt.post_id
AND t.id = ".$this->db->escape($tag_id).")";
$results = $this->db->query($sql)->result();
return $results;
我想得的是以下内容:
{
"data": [
{
"id": "28",
"title": "blabla",
"content": "<p>hello<\/p>",
"user_id": "1",
"created_date": "2014-08-18 23:57:22",
"slug": "blabla-2014-08-18-235722",
"tags": [
{
"id": 1
"tag": "test",
},
{
"id": 2
"tag": "test2",
}
]
},
{
"id": "34",
"title": "test2",
"content": "<p>test2<\/p>",
"user_id": "1",
"created_date": "2014-08-23 21:41:00",
"slug": "test2-2014-08-23-214100"
"tags": [
{
"id": 3
"tag": "testa",
},
{
"id": 1
"tag": "test",
}
]
}
],
"success": true
}
答案 0 :(得分:1)
我假设您很乐意向数据库发送两个请求。
首先,获取给定标签的所有帖子:
SELECT * FROM blog_posts bp
WHERE EXISTS (SELECT * FROM blog_tags bt INNER JOIN
tags t ON t.id = bt.tag_id
WHERE bp.id = bt.post_id
AND t.tag = @SearchTag)
其次,我想通过帖子链接到您要查找的标签:
SELECT * FROM tags t
WHERE EXISTS ( -- Here we link two tags via blog_tags
SELECT * FROM blog_tags bt1 INNER JOIN
blog_tags bt2 ON bt1.post_id = bt2.post_id
AND bt1.tag_id != bt2.tag_id INNER JOIN
tags t ON t.id = bt1.tag_id
WHERE t.tag = @SearchTag
AND t.id = bt2.tag_id
)
答案 1 :(得分:0)
我一气呵成,继续@ Bulat的代码。
SELECT *,
GROUP_CONCAT(DISTINCT bt.tag_id) as tags_id,
GROUP_CONCAT(DISTINCT t.tag) as tags
FROM blog_posts bp
INNER JOIN blog_tags bt
ON bt.post_id = bp.id
ON t.id = bt.tag_id
GROUP BY bt.post_id
ORDER BY bp.created_date DESC
然后我将tags和tags_id作为带有foreach循环的数组返回
$results = $this->db->query($sql)->result();
foreach($results as $result) {
$result->tags_comma = $result->tags;
strpos($result->tags, ',') ? $result->tags = explode(',', $result->tags) : $result->tags = array($result->tags);
$result->tags_comma = str_replace(',', ', ', $result->tags_comma);
}
foreach($results as $result) {
$result->tags_id_comma = $result->tags_id;
strpos($result->tags_id, ',') ? $result->tags_id = explode(',', $result->tags_id) : $result->tags_id = array($result->tags_id);
$result->tags_id_comma = str_replace(',', ', ', $result->tags_id_comma);
}
答案 2 :(得分:0)
根据这篇文章经过几个小时后, How to Write Many-To-Many Search Queries in MySQL and Hibernate 我已经找到了一种方法可以一次性完成。到目前为止,它对我有用。
请注意我正在使用此表名: noticias as blog_posts,tags_noticias as blog_tags,tasg as tag
SELECT a.id, a.titulo, GROUP_CONCAT(tags.descripcion) as tags
FROM noticias a
INNER JOIN (SELECT at.id_noticia
FROM tags_noticias at
INNER JOIN noticias a
ON a.id = at.id_noticia
INNER JOIN tags t
ON t.id = at.id_tag
WHERE t.descripcion IN ("tag1","tag2")
GROUP BY at.id_noticia
HAVING Count(at.id_noticia) = 2) aa
ON a.id = aa.id_noticia
JOIN tags_noticias ON tags_noticias.id_noticia = a.id
JOIN tags ON tags.id = tags_noticias.id_tag
GROUP BY tags_noticias.id_noticia