正如你们中的一些人可能已经从我之前的问题中了解到的那样,我目前正在开发一个博客系统。
这一次,我坚持要获取特定类别的所有帖子及其类别。
以下是用于创建三个必需表的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;
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
条件下,但我不知道在哪里。请指出我正确的方向。
答案 0 :(得分:1)
我怀疑您的CONCAT功能可能存在问题,因为它混合了不同类型的引号。我认为"["
和"]"
应分别为'['
和']'
。
否则,问题似乎与其中一个连接有关。特别是,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也不会评估。结果,整个组都将被丢弃。