首页 > 解决方案 > MySQL 标签系统(3 个表) - 如何选择最后 10 个发布的帖子以及与每个帖子关联的所有标签?

问题描述

我正在为我的网站实现一个标签系统,使用 PHP + MySQL。

在我的数据库中,我有三个表:

帖子

ID 标题 约会时间

主键:id

标签

ID 标签 蛞蝓

主键:id | 关键:蛞蝓

标签地图

ID 标签

主键:两者

(id = 帖子中的帖子 ID;标签 = 标签中的标签 ID)

每个帖子可能有一个或多个标签,或者没有标签,与之关联。

现在我需要选择 - 并在同一页面上显示 - 最后 10 个(不少于,不多)发布的帖子以及与这些帖子关联的所有标签。

这是我尝试过的:

SELECT 
  p.title, 
  t.slug, 
  t.tag 
FROM 
  posts p 
  LEFT JOIN tagsmap tm ON p.id = tm.id 
  LEFT JOIN tags t ON tm.tag = t.id 
WHERE 
  p.datetime <= NOW() 
ORDER BY 
  p.id DESC 
LIMIT 
  10

它可以工作,但是这样做,具有两个标签的帖子会显示两次,而我只需要显示每个帖子一次。

然后我添加了

GROUP BY p.id

但是,这样一来,每篇文章我只能得到一个标签。

我不知道如何解决这个问题(我对 MySQL 不是很有经验)。

你能给我什么建议吗?

SQL小提琴

PS:我需要的是一个 SQL 端(不是 PHP 端)的解决方案(就性能而言最好的)。尽管如此,任何进一步的建议将不胜感激。

标签: mysql

解决方案


首先选择最新的 10 个帖子,然后加入其他表。
然后按帖子分组并使用GROUP_CONCAT()以逗号分隔的字符串为每个帖子组合所有 slugs 和标签:

SELECT p.title, 
       GROUP_CONCAT(t.slug ORDER BY t.id) slugs, 
       GROUP_CONCAT(t.tag ORDER BY t.id) tags 
FROM (SELECT * FROM posts WHERE datetime <= NOW() ORDER BY datetime DESC LIMIT 10) p 
LEFT JOIN tagsmap tm ON p.id = tm.id 
LEFT JOIN tags t ON tm.tag = t.id 
GROUP BY p.id
ORDER BY p.datetime DESC;

请参阅演示


推荐阅读