2

在 MySQL 数据库中,我试图在许多数字属性中找到最相似的行。此问题与此问题类似,包括灵活数量的比较和连接表。

数据库

该数据库由两个表组成。第一个表,用户,是我想要比较的。

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

任务

我想找到与给定用户“最相似”的用户,平等地评估所有排名项目(以及自我得分)。因此,完美匹配将是用户以完全相同的方式对所有相同的项目进行排名并且对自己的评分相同,而下一个最佳选择将是一个项目的排名略有不同的用户。

我遇到了困难:

  • 以有效的方式连接两个表
  • 处理并非所有用户都对相同项目进行排名的事实。我们只想比较相同项目的排名。

有人可以帮我构建一个合理的查询吗?我对 MySQL 不是很擅长,如果这个答案很明显,我很抱歉。

输出

如果用户 4 将自己排名为 8 并且项目 1=>4 和 2=>5,那么我希望查询用户 4 的最近用户以返回 1,即最近用户的 user_id。

4

2 回答 2

1

在对@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

-- 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
于 2012-11-18T20:28:07.157 回答
0
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
于 2012-11-18T19:34:58.977 回答