【问题标题】:MySQL - How to query items by tags, order by matched tag countMySQL - 如何按标签查询项目,按匹配的标签计数排序
【发布时间】:2011-08-29 13:09:48
【问题描述】:

我的架构如下所示:

items ( id, title, blah )
tags (id, name )
item_tags ( item_id, tag_id )

我想列出所有项目,其中项目的标签“在”一个选定标签的数组中,然后按与选择匹配的标签数量排序(例如 [1,2,3])

到目前为止我所拥有的是:

SELECT *, COUNT(item_tags.tag_id) AS tag_count
FROM items
JOIN item_tags
ON item_tags.item_id = items.id
WHERE item_tags.tag_id IN (1, 2, 3)
GROUP BY items.id
ORDER BY tag_count DESC

这很好用,除了 tag_count 只是获取所选项目的标签总数,我希望它是包含在 (1, 2, 3) 中的所选标签数。

带有标签 (1, 2, 3) 的项目应该位于带有标签 (1, 5, 6, 7) 的项目之前。

如果有这样的解决方案,我正在使用 Kohana 3 的 ORM。

【问题讨论】:

    标签: mysql sql kohana kohana-3 kohana-orm


    【解决方案1】:

    只需将您的 SELECT 更改为:

    SELECT *, COUNT(*) AS tag_count
    .....
    

    【讨论】:

      【解决方案2】:

      我认为您真正想要的是 GROUP_CONCAT( tag_id ) (也许除了您的计数之外)。组 concat 将连接您的 ID,例如您显示的... 1、2、3 和 1、5、6、7。如果您使用该列作为您的 order by,那么您应该很好。

      现在,也就是说,您可能必须强制对连接过程进行一些格式化,以处理 1、2、3 之前出现的 1、10、100 之类的事情。因此,如果将连接的 ID 字符串格式化为... 2或3个职位,你会得到

      001, 002, 003 
      vs
      001, 005, 006, 007 
      vs
      001, 010, 100
      

      HTH

      【讨论】:

      • -1 组连接不会改变分组行数(当前由COUNT(*) 表示)错误的事实。正如您所指出的,它只会产生额外的排序问题。
      • 不过,使用GROUP_CONCAT 来调试SQL 可能是个好主意。通过在SELECT 语句中添加类似CAST(GROUP_CONCAT(tag_id SEPARATOR ',') AS CHAR) 的内容,应该可以准确地查看每个项目计算了哪些标签。
      • 谢谢你 - 我现在可以更清楚地看到我的原始查询正在按照我的计划工作
      • @Tom,很高兴听到我的解决方案提供了帮助...有时,通过研究其他替代方案可以让您了解 SQL 在幕后所做的事情,然后删除使用的“调​​试”列用于分析(@Ivar Bonsaksen)
      • @Ivar, DRapp 是的,GROUP CONCAT 在那里绝对有用。该列似乎有助于向最终用户显示哪些标签与列出的项目匹配,而无需对每个项目进行单独的查询(我当然需要单独的查询来显示标签的名称) - 你认为GROUP CONCAT 是一个可行的解决方案吗?
      猜你喜欢
      • 2011-04-16
      • 1970-01-01
      • 1970-01-01
      • 2013-01-14
      • 1970-01-01
      • 2022-01-09
      • 1970-01-01
      • 2011-05-16
      • 1970-01-01
      相关资源
      最近更新 更多