mysql 通过GROUP BY和JOINS获取MAX值的数据行

gwo2fgha  于 2024-01-05  发布在  Mysql
关注(0)|答案(2)|浏览(306)

我正在使用ml100k数据集编写一个查询,可以为我获取每个年龄段最受欢迎的电影。
下面是我的表是如何定义的。

用户

第一个月

收视率

userid | movieid | rating | ts
到目前为止我所做的
1.由于没有显式定义计数,所以我编写了一个查询来查找它。

  1. SELECT age, movieid, COUNT(*) AS mcount
  2. FROM ratings
  3. JOIN users ON id = userid
  4. GROUP BY age, movieid

字符串
这给了我每个年龄段每部电影的计数。

  1. 10 1 1
  2. 11 1 1
  3. 13 1 3
  4. 14 1 1
  5. 15 1 2
  6. 16 1 4
  7. 17 1 4
  8. 18 1 6
  9. 19 1 15
  10. 20 1 22
  11. 21 1 14


1.找出每个年龄段的最大值

  1. SELECT age, MAX(mcount) AS mc
  2. FROM (
  3. SELECT age, movieid, COUNT(*) AS mcount
  4. FROM ratings
  5. JOIN users ON id = userid
  6. GROUP BY age, movieid
  7. ) t1
  8. GROUP BY age
  1. 7 1
  2. 10 1
  3. 11 1
  4. 13 5
  5. 14 3
  6. 15 5
  7. 16 5
  8. 17 11
  9. 18 16
  10. 19 21
  11. 20 25
  12. 21 23

的字符串
这给了我年龄和最大计数。然而,我还想要相应的电影ID,这是我一直卡住的地方。我的想法是将这些结果与第一个表连接起来,但它不起作用。有没有其他的替代方法可以尝试?这是我使用的查询。

  1. SELECT users.age, ratings.movieid, count(*) as mc2
  2. FROM ratings JOIN users ON id = userid
  3. INNER JOIN
  4. (
  5. SELECT age, MAX(mcount) AS mc
  6. FROM (
  7. SELECT age, movieid, COUNT(*) AS mcount
  8. FROM ratings
  9. JOIN users ON id = userid
  10. GROUP BY age, movieid
  11. ) t1
  12. GROUP BY age
  13. )t2
  14. ON t2.age = users.age
  15. WHERE mc2=t2.mc
  16. GROUP BY users.age, ratings.movieid;

vh0rcniy

vh0rcniy1#

你可以这样做:

  1. SELECT t.age, t.movieid, t.mcount
  2. FROM (
  3. SELECT age, movieid, COUNT(*) AS mcount
  4. FROM ratings
  5. JOIN users ON id = userid
  6. GROUP BY age, movieid
  7. ) t
  8. LEFT JOIN (
  9. SELECT age, movieid, COUNT(*) AS mcount
  10. FROM ratings
  11. JOIN users ON id = userid
  12. GROUP BY age, movieid
  13. ) t2
  14. ON t.age = t2.age AND
  15. t.movieid <> t2.movieid AND
  16. t.mcount < t2.mcount
  17. WHERE t2.age IS NULL

字符串
说明:

  • 第一次子选择
  • 连接ratingsusers
  • onusersid
  • agemovieid分组
  • 来找到
  • 选择您需要的字段
  • 生成所有组
  • 第二次子选择
  • 与第一实施例相同
  • 我们LEFT JOIN两组,
  • 匹配age
  • 不同的movieid(因此我们将进行合理的计数比较)
  • 并且第一mcount小于第二mcount
  • 因为我们想找到第一组的物品
  • 没有更高计数的匹配
  • 所以我们搜索匹配的次数
  • WHERE子句中,我们排除了在第二组中找到的匹配计数高于第一组的情况

小提琴:http://sqlfiddle.com/#!9/f8 defe/6

展开查看全部
p1iqtdky

p1iqtdky2#

8.2.0 - vnk

  1. WITH cte AS (
  2. SELECT age,
  3. movieid,
  4. COUNT(*) AS mcount,
  5. RANK() OVER (PARTITION BY age, ORDER BY COUNT(*) DESC) rnk
  6. FROM ratings
  7. JOIN users ON id = userid
  8. GROUP BY 1, 2
  9. )
  10. SELECT age,
  11. GROUP_CONCAT(movieid) movie_ids,
  12. mcount
  13. FROM cte
  14. WHERE rnk = 1
  15. GROUP BY 1, 3

字符串
多部电影可能具有相同的最高评级。因此,将向外部查询添加聚合。如果您希望在许多行中(每行一部电影)而不是在一个输出行中接收这些重复内容,请删除外部聚合。
如果您只需要一部电影,那么您必须定义额外的排序标准(在窗口定义中展开ORDER BY),以便从所有可能的电影中仅选择一部电影。
或者,如果你需要在任何不确定/随机的,然后简单地删除外部聚合,并使用ROW_NUMBER()而不是RANK()。

展开查看全部

相关问题