现状
你们中的一些人可能已经从我之前的问题中了解到,我目前正在开发一个博客系统。
这一次,我只能获取特定类别的所有帖子及其类别。
数据库
以下是创建所需的三个表的 SQL 命令。
发布
create table Post(
headline varchar(100),
date datetime,
content text,
author int unsigned,
public tinyint,
type int,
ID serial,
Primary Key (ID),
)ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
author
是创建帖子的用户的 ID,public
确定帖子是可以被所有人阅读还是只是草稿和 type
确定它是博客文章 (0
) 还是其他内容。
类别
create table Kategorie(
name varchar(30),
short varchar(200),
ID serial,
Primary Key (name)
)ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Post_Kategorie
create table Post_Kategorie(
post_ID bigint unsigned,
kategorie_ID bigint unsigned,
Primary Key (post_ID, kategorie_ID),
Foreign Key (post_ID) references Post(ID),
Foreign Key (kategorie_ID) references Kategorie(ID)
)ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
查询
这是我当前的查询,用于获取所有标记有特定类别的帖子,该类别由类别的 ID 确定:
SELECT Post.headline, Post.date, Post.ID,
CONCAT(
"[", GROUP_CONCAT('{"name":"',Kategorie.name,'","id":',Kategorie.ID,'}'), "]"
) as "categorys"
FROM Post
INNER JOIN Post_Kategorie
ON Post.ID = Post_Kategorie.post_ID
INNER JOIN Kategorie
ON Post_Kategorie.kategorie_ID = 2
WHERE Post.public = 1
AND Post.type = 0
GROUP BY Post.headline, Post.date
ORDER BY Post.date DESC
LIMIT 0, 20
该查询适用于列出所有标记为特定类别的帖子,但是 categorys
-列会混淆,因为每个列出的帖子都有所有可用的类别(Kategorie< 中列出的每个类别
-表)。
我确定问题出在 INNER JOIN
条件上,但我不知道出在哪里。请指出正确的方向。
最佳答案
我怀疑您的 CONCAT 函数可能存在问题,因为它混合了不同类型的引号。我觉得"["
and "]"
应该分别是'['
and ']'
.
否则,问题似乎出在其中一个联接上。特别是INNER JOIN Kategorie
没有指定加入条件,我认为应该是Post_Kategorie.Kategorie_ID = Kategorie.ID
。
因此整个查询应该是这样的:
SELECT Post.headline, Post.date, Post.ID,
CONCAT(
"[", GROUP_CONCAT('{"name":"',Kategorie.name,'","id":',Kategorie.ID,'}'), "]"
) as "categorys"
FROM Post
INNER JOIN Post_Kategorie
ON Post.ID = Post_Kategorie.post_ID
INNER JOIN Kategorie
ON Post_Kategorie.Kategorie_ID = Kategorie.ID
WHERE Post.public = 1
AND Post.type = 0
GROUP BY Post.headline, Post.date
HAVING MAX(CASE Post_Kategorie.kategorie_ID WHEN 2 THEN 1 ELSE 0 END) = 1
ORDER BY Post.date DESC
LIMIT 0, 20
Post_Kategorie.kategorie_ID = 2
条件已修改为 CASE 表达式并移至 HAVING
子句,并与 MAX( )
聚合函数。其工作方式如下:
如果帖子被标记为属于
Kategorie.ID = 2
的一个或多个标签,则 CASE 表达式将返回 1,并且 MAX 的计算结果也将是 1。因此,所有组都将有效并保留在输出中。如果帖子所标记的标签不属于所述类别,则 CASE 表达式的计算结果永远不会为 1,MAX 也不会。结果,整个组将被丢弃。
关于mysql - 获取特定类别的所有帖子,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6562178/