在编写SQL查询方面,我并不是很先进,并且我正在尝试找出一个查询,该查询将在product页面上显示product页面上的评级,该用户对product在product中最可比的品味到访问该页面的用户。我在下面提供了一个方案,希望可以轻松了解我要实现的目标。

示例MySQL数据库

row_id user_id rating product_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。

目标
我正在尝试找出最清洁,最有效的方法,以根据所有其他用户都提交评级的所有其他product来显示product_id#3给出的评级。

我希望这也忽略了任何在1-50之间至少提交1个product评级和51-100之间至少1个product评级的用户(因此,基本上我想排除那些始终给出高或始终给出较低评分的用户)。

如果没有根据上述条件提交评级的用户,则需要仅返回“ n/a”。

消除过程
user_id#5的行将被排除在外,因为此用户尚未评级product_id#3。

user_id#4的行也将被排除在外,因为该用户尚未提交1-50之间的任何评分。

这使用户#2和用户#3剩下,因为他们都符合1-50之间的product以及51-100之间的product的评级。

product#1的评分为41,用户#1的评分为41,用户#2(差2)评级为39,用户#3评分26(差异为15)。

product#2由用户#1评级为67,用户#2(差1)的评分为66,用户#3(差异为5)额定为72。

将其列入平均值,用户#2与用户#1给出的评分相比,用户的平均差异为1.5,而用户#3与评分用户#1相比,用户#3的平均差异为10。

结果
根据示例数据库表,用户#2将具有与用户#1的最相同的评分,并且product#3的预期输出应为:55

弄清楚如何完成这项工作的任何帮助将不胜感激。

分析解答

我创建了一个进行必要操作的小提琴:http://sqlfiddle.com/#!9/e1caa2/1

以下是完整的SQL查询。 它的结构如下:

  • 选择所有审查过product3的用户3
  • 选择所有具有适当评分的用户(至少一个> 50和一个<50)
  • 内部加入以上两个结果,以找到满足这两个条件的用户
  • 直接在product_id上加入原始表格,以获取用户之间的不同评分
  • 添加正确的加入标准,以便将用户1的评分与满足标准的用户的评分进行比较
  • 计算右键中的评分之间的绝对差异
  • 绝对差异的平均值
  • 使用原始表加入用户平均
  • 订购平均差异
  • 添加标准以获得product“ 3”的评分
  • 最后限制为1个评分

SQL查询:

SELECT rating
FROM table1 t1
INNER JOIN
  (SELECT user_id,
          avg(difference) AS avg_difference
   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) t2 ON t1.user_id = t2.user_id
WHERE t1.product_id='3'
ORDER BY avg_difference ASC
LIMIT 1

为了完整,SQL小提琴中使用的架构:

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');