MySQL查询从一个表中获得最佳排名,并使用UPDATE结果获得另一个

时间:2015-09-22 09:11:36

标签: php mysql

我有一个排名委员会,为每个性别男性和女性提供最好的前100个博客。

我有一个博客表:

PRIMARY
blogs_id  users_id  blogs_score  blogs_score_time      gender
    1         11        2852     2015-09-09 05:21:51     m <-- same score but older date
    2         23        2146     2015-09-10 07:31:54     m
    3         23        2146     2015-09-10 07:32:26     m
    4         23        2852     2015-09-10 04:42:15     m <-- same score but newer date
    5         51        1793     2015-09-11 08:15:55     f
    6         88        2947     2015-09-11 09:33:18     f 

我有一个用户表:

PRIMARY
  id  best_rank  gender
  11      0         m
  23      0         m
  51      0         f
  88      0         f

我需要为博客表中的每个用户COUNT最佳排名(使用MAX(blogs_score)和MAX(blogs_score_time)),并使用用户表 INSERT / UPDATE排名最高的每个性别的前100位用户的最佳排名,结果应为:

PRIMARY
  id  best_rank  gender
  11      2         m
  23      1         m
  51      2         f
  88      1         f

其中用户id 11具有最佳等级2,因为用户id 11与用户23具有相同的分数但是比用户23更早的日期。其中用户51由于女性组而具有等级2。我添加了列blogs_score_time以防止排名排名。而2015-09-10的日期意味着9月10日。

最后的想法是在用户的个人资料中显示排名位置,一旦有人投票(博客表中blogs_score更改),best_rank列中的users列1}}表必须使用新排名重新计算更新所有在特定性别组中排名最高的100位用户。

如何根据我的需要调整和修复此(不工作)查询?

 $sql->query("UPDATE users
            JOIN (SELECT b.users_id,
                         @curRank := @curRank + 1 AS rank,
                         MAX(blogs_score), MAX(blogs_score_time)
                  FROM blogs b
                         JOIN (SELECT @curRank := 0) r
                  ORDER BY  b.blogs_score DESC, p.blogs_score_time DESC LIMIT 100
                 ) ranks ON (ranks.users_id = users.id)
            SET users.best_rank = ranks.rank");

或如何调整和修复此(不工作)查询

 $sql->query("INSERT INTO users (best_rank, id)
                  SELECT @rank := @rank + 1 AS rank, b.users_id
                       FROM blogs b
                       LEFT JOIN users u ON b.users_id = u.id
                  GROUP BY b.users_id, b.blogs_score, b.blogs_score_time, b.gender
                  ORDER BY b.blogs_score DESC, b.blogs_score_time DESC
              ON DUPLICATE KEY UPDATE best_rank = VALUES(rank)");

请帮我解决问题。我没有在stackoverflow上找到任何类似的解决方案,单独编写这样的查询对我来说似乎很复杂。

提前多多感谢!

2 个答案:

答案 0 :(得分:1)

UPDATE users u, (
SELECT 
( 
    CASE gender 
    WHEN @curType 
    THEN @curRow := @curRow + 1 
    ELSE @curRow := 1 AND @curType := gender END
) + 1 AS rank, users_id, blogs_score, blogs_score_time, gender 
FROM blogs, 
(SELECT @curRow := 0, @curType := '') r
ORDER BY gender, blogs_score DESC, blogs_score_time DESC
) r1
SET u.best_rank = r1.rank
WHERE
u.id = r1.users_id

它有2件作品:

  1. 内部选择查询根据性别,分数和时间生成排名
  2. 更新具有相应排名的用户表。

答案 1 :(得分:0)

我认为你应该在ORDER BY之前以这种方式添加GROUP BY子句

$sql->query("UPDATE users
              JOIN (SELECT b.users_id,
                         @curRank := @curRank + 1 AS rank,
                         MAX(b.blogs_score), MAX(b.blogs_score_time   )
                  FROM blogs b
                         JOIN (SELECT @curRank := 0) r
                  GROUP BY b.user_id, rank
                  ORDER BY  b.blogs_score DESC, p.blogs_score_time DESC LIMIT 100
                 ) ranks ON (ranks.users_id = users.id)
            SET users.best_rank = ranks.rank");