mysql - 获取特定类别的所有帖子

标签 mysql sql select join

现状

你们中的一些人可能已经从我之前的问题中了解到,我目前正在开发一个博客系统。

这一次,我只能获取特定类别的所有帖子及其类别。

数据库

以下是创建所需的三个表的 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/

相关文章:

mysql - 带有 mySQL 连接的行号

mysql - 将日期和时间与今天的日期和时间进行比较

mysql - 从 MySQL 表中选择 10 条具有唯一作者的最新评论

mysql - 为什么SQL中没有 "first greater/less than [or equal to]"比较运算符?

android - 单词搜索游戏 : How to Select Multiple Items in a GridView By Dragging? (Android)

mysql - 查找一个月内不同 worker 的数量

mysql - SQL 返回搜索集和结果

php mysql..无法将变量分配给数据库中的字段名称

php - 电子邮件字段未保存到数据库 - Android 注册页面

sql - Redshift 未记录到 STL_WLM_RULE_ACTION