【问题标题】:MySQL Order by number of matches in sibling tableMySQL 按兄弟表中的匹配数排序
【发布时间】:2016-11-30 19:53:28
【问题描述】:

我有一个项目表和一个可以附加到这些项目的标签表。在更基本的方式中,它就像 StackOverflow 问题和标签,将项目视为问题和标签以及 StackOverflow 标签。

每个项目都可以用无限的标签进行标记,但我想按照匹配的标签数量的顺序返回结果。

我会给你我的表结构,然后是一个例子。

tags

id | tag_name
 1   delicious
 2   spicy
 3   sweet

item_tags

id | item_id | tag_id | created
 1   1         1        TIMESTAMP
 2   1         2        TIMESTAMP
 3   2         1        TIMESTAMP
 4   2         2        TIMESTAMP
 5   2         3        TIMESTAMP

如您所见,如果我搜索标签“甜、辣、美味”,那么第 2 项将匹配所有三个标签,而第 1 项将仅匹配最后两个标签。我显然想根据匹配标签的更多数量首先返回第 2 项。

如果我有这样的查询:

SELECT * FROM item_tags WHERE tag_id IN(1,2,3) GROUP BY item_id ORDER BY NumberOfMatches

其中NumberOfMatchesitem_tags 表中匹配的标签数。

希望在没有 UNION 或任何主要内容的情况下执行此操作,但欢迎所有建议。

【问题讨论】:

  • 为什么不计算您的item_id 并按您的回报排序?
  • SELECT COUNT(tag_id) AS NumberOfMatches, item_tags.* FROM item_tags WHERE tag_id IN(1,2,3) GROUP BY item_id ORDER BY NumberOfMatches DESC

标签: mysql sql


【解决方案1】:

你们都在那里,试试这个:

select
    it.item_id
from item_tags it
join tags t on it.tag_id = t.id
where t.id in (1, 2, 3)
group by it.item_id
order by count(distinct t.id) desc

SQLFiddle demo here

如果你想通过tag_name获取记录,你必须使用join,比如:

select
    it.item_id
from item_tags it
join tags t on it.tag_id = t.id
where t.tag_name in ('sweet', 'pic', 'delicious')
group by it.item_id
order by count(distinct t.id) desc

或者如果您知道确切的标签 ID,@Daerik 的方法会更有效。而关于性能,这里两种方案可能没有太大区别。

【讨论】:

  • 感谢您的快速回答。您能否在 Daerik 的评论中解决解决方案并讨论这两种方法的任何潜在性能差异?对不起,我是 MySQL 的新手。
  • @DanL 更新了答案,请查收。
猜你喜欢
  • 2011-08-04
  • 1970-01-01
  • 1970-01-01
  • 2018-10-22
  • 1970-01-01
  • 2013-09-14
  • 2011-08-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多