我在编写 SQL 查询方面不是很先进,我正在尝试找出一个查询,该查询将在产品页面上显示与访问该页面的用户对产品品味最相似的用户的评级。我在下面提供了一个场景,希望可以让您轻松理解我想要实现的目标。
MySQL 数据库示例
行_id | 用户ID | 评分 | 产品_id |
---|---|---|---|
1 | 1 | 41 | 1 |
2 | 2 | 39 | 1 |
3 | 3 | 26 | 1 |
4 | 4 | 56 | 1 |
5 | 1 | 67 | 2 |
6 | 2 | 66 | 2 |
7 | 3 | 72 | 2 |
8 | 4 | 82 | 2 |
9 | 5 | 64 | 2 |
10 | 2 | 55 | 3 |
11 | 3 | 47 | 3 |
12 | 4 | 70 | 3 |
场景
访问该页面的人是 user_id #1,他们正在查看 Product_id #3。
目标
我正在尝试找出最干净、最有效的方法来显示对 user_id #3 给出的评级,该评级来自与 user_id #1 具有最相同评级的用户(基于两个用户都提交了评级的所有其他产品)。
我希望这也能忽略任何未提交至少 1 个 1-50 之间的产品评级和至少 1 个 51-100 之间的产品评级的用户(所以基本上我想排除总是给出高或总是给出低的用户一切的评级)。
如果没有用户根据上述标准提交评分,则只需返回“n/a”即可。
消除过程
user_id #5 的行将被排除,因为该用户尚未对 Product_id #3 进行评级。
user_id #4 的行也将被排除,因为该用户尚未提交 1-50 之间的任何评分。
这使得用户 #2 和用户 #3 留下来,因为他们都满足对 1-50 之间的产品以及 51-100 之间的产品提交评级的标准。
产品 #1 被用户 #1 评为 41,被用户 #2 评为 39(相差 2),被用户 #3 评为 26(相差 15)。
产品 #2 被用户 #1 评分为 67,被用户 #2 评分为 66(相差 1),被用户 #3 评分为 72(相差 5)。
将其计算为平均值,与用户 #1 给出的评分相比,用户 #2 的平均差异为 1.5,而用户 #3 与用户 #1 对相同产品给出的评分的平均差异为 10。
结果
根据示例数据库表,用户 #2 将具有与用户 #1 最相同的评级,并且产品 #3 的预期输出应为:55
任何有关如何完成这项工作的帮助将不胜感激。
我创建了一个小提琴来执行必要的操作:http://sqlfiddle.com/#!9/e1caa2/1
下面是完整的sql查询。 其结构如下:
product_id
以获得用户之间的不同评分SQL查询:
SELECT user_id
FROM
(SELECT t2.user_id,
abs(t1.rating-t2.rating) AS difference
FROM table1 t1
RIGHT JOIN table1 t2 ON t1.product_id = t2.product_id
WHERE t1.user_id = '1'
AND t2.user_id in
(SELECT user_with_appropriate_rating.user_id
FROM
(SELECT user_id
FROM
(SELECT user_id,
max(rating) AS maxrating,
min(rating) AS minrating
FROM table1
GROUP BY user_id) user_with_rating
WHERE user_with_rating.maxrating >50
AND user_with_rating.minrating<50) user_with_appropriate_rating
INNER JOIN
(SELECT DISTINCT user_id
FROM table1
WHERE product_id = '3') user_has_reviewed_product ON user_with_appropriate_rating.user_id = user_has_reviewed_product.user_id)) product_difference
GROUP BY user_id
ORDER BY avg(difference)
LIMIT 1
为了完整起见,sql fiddle 中使用的模式:
CREATE TABLE IF NOT EXISTS `table1` (
`row_id` int(1) NOT NULL,
`user_id` int(1) NOT NULL,
`rating` int(1) NOT NULL,
`product_id` int(1) NOT NULL,
PRIMARY KEY (`row_id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `table1` (`row_id`, `user_id`, `rating`, `product_id`) VALUES
('1', '1', '41', '1'),
('2', '2', '39', '1'),
('3', '3', '26', '1'),
('4', '4', '56', '1'),
('5', '1', '67', '2'),
('6', '2', '66', '2'),
('7', '3', '72', '2'),
('8', '4', '82', '2'),
('9', '5', '64', '2'),
('10', '2', '55', '3'),
('11', '3', '47', '3'),
('12', '4', '70', '3');