MySQL查询以查找最相似的数字行
在MySQL数据库中,我试图在许多数字属性中找到最相似的行。此问题类似于,但包括灵活的比较数量和联接表 数据库 数据库由两个表组成。第一个表,users,是我想要比较的MySQL查询以查找最相似的数字行,mysql,similarity,Mysql,Similarity,在MySQL数据库中,我试图在许多数字属性中找到最相似的行。此问题类似于,但包括灵活的比较数量和联接表 数据库 数据库由两个表组成。第一个表,users,是我想要比较的 id | self_ranking ---------------------------------- 1 | 9 2 | 3 3 | 2 第二个表是用户给特定项目的一系列分数 id | user_id | item_id | score -------------------------
id | self_ranking
----------------------------------
1 | 9
2 | 3
3 | 2
第二个表是用户给特定项目的一系列分数
id | user_id | item_id | score
----------------------------------
1 | 1 | 1 | 4
2 | 1 | 2 | 5
3 | 1 | 3 | 8
4 | 1 | 4 | 3
任务
我想找到与给定用户“最相似”的用户,对所有排名项目进行同等评估(以及自我评分)。因此,一个完美的匹配将是用户以完全相同的方式对所有相同的项目进行排名,并对自己进行相同的评级,而下一个最佳选择将是一个项目的排名略有不同的用户
我在以下方面遇到了困难:
- 以有效的方式连接两个表
- 处理并非所有用户都对相同的项目进行排名这一事实。我们只想比较相同项目的排名
如果用户4将自己排名为8,项目1=>4和2=>5,那么我希望查询用户4的最近用户,返回1,即最近用户的用户id。在@eggyal方法的稍微改进中,我加入了我们能够匹配的项目数
SELECT u2.user_id
-- join our user to their scores
FROM (users u1 JOIN scores s1 USING (user_id))
-- and then join other users and their scores
JOIN (users u2 JOIN scores s2 USING (user_id))
ON s1.item_id = s2.item_id
AND u1.user_id != u2.user_id
-- filter for our user of interest
WHERE u1.user_id = ?
-- group other users' scores together
GROUP BY u2.user_id
-- and here's the magic: order in descending order of "distance" between
-- our selected user and all of the others: you may wish to weight
-- self_ranking differently to item scores, in which case just multiply
-- appropriately
ORDER BY SUM(ABS(s2.score - s1.score))
+ ABS(u2.self_ranking - u1.self_ranking) DESC
SELECT u2.user_id
-- join our user to their scores
FROM (users u1 JOIN scores s1 USING (user_id))
-- and then join other users and their scores
JOIN (users u2 JOIN scores s2 USING (user_id))
ON s1.item_id = s2.item_id
AND u1.user_id != u2.user_id
-- filter for our user of interest
WHERE u1.user_id = ?
-- group other users' scores together
GROUP BY u2.user_id
-- subtract the degree of difference in correlating scores from the number of correlating scores
ORDER BY (SUM(s1.item_id = s2.item_id) -
( SUM(ABS(s2.score - s1.score) + ABS(u2.self - u1.self) ) ) ) DESC
我不确定自己是否理解用户。自我排名与您的问题相关(如果确实相关)?在这种情况下,您可以用预期输出表编辑您的问题吗?@eggyal,它应该被视为另一个排名(即用户将自己列为“项目”)。您可以想象您需要什么,那么,你能将预期的输出结果以与当前表格相同的格式显示吗?为什么self_排名不依赖于“完美匹配”?这个句子中的“稍微”是什么意思?谢谢你的回答。恐怕我在用户id连接上出错,因为我错误地列出了错误的数据库格式。在用户表中,它只是id(如上编辑)。@MorganteOrionPell:然后将s1上使用(用户id)的
替换为。用户id=u1.id
等。它不应该是最后的ASC,而不是DESC吗?我想找到差异最小的用户。