MySQL 按同级表中的匹配项数量排序

标签 mysql sql

我有一个项目表和一个可以附加到这些项目的标签表。从更基本的角度来看,它就像 StackOverflow 问题和标签,将项目视为问题和标签以及 StackOverflow 标签。

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

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

标签

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 或任何重大内容的情况下做到这一点,但对所有建议持开放态度。

最佳答案

你们都已经到了,试试这个:

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 的方法会更有效。而关于性能,这里两种解决方案可能没有太大差异。

关于MySQL 按同级表中的匹配项数量排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40880033/

相关文章:

mysql - ASP.NET 中的全局变量和 session

MySQL,获取购买次数最多的三个客户 :

sql - SQL 命令中的 TIMESTAMP 和 CURRENT_TIMESTAMP 问题

mysql - 在 MySQL 中使用 "TYPE = InnoDB"会引发异常

mysql - T-SQL (transact-SQL) 在 SQLite 和其他 SQL 数据库中有效吗?

c# - AES _Encryption 在 Mysql 中,在 C#.Net 中解密

mysql - 清除数据库 - 计算清除/未清除的表

MySQL 计数/跟踪条纹或连续日期

MySQL 没有从索引中选择正确的行数

mysql - 与 CRM 相比,MSReport 显示的到期日期晚了 1 天?