如何在无ID列的MySQL表中按Keyword和Day更新Ranking字段
解决MySQL按分组生成连续排名的问题
嘿,我来帮你搞定这个排名计算的需求!你需要的是按Keyword和Day两个字段分组,每组内的Ranking从1开始依次递增,同组第一行排名为1,后续行在前序基础上加1对吧?
先说说你原来代码的问题
你之前尝试用全局变量@ID累加的方式,会导致所有行的排名一直递增,没法实现按Keyword+Day分组后重置排名的效果,得针对分组场景调整写法。
方案1:用窗口函数(MySQL 8.0+推荐)
如果你的MySQL版本是8.0及以上,窗口函数是最简洁直观的解决方案,不需要手动维护变量:
SELECT Keyword, Asin, Day, ROW_NUMBER() OVER (PARTITION BY Keyword, Day ORDER BY Asin) AS Ranking FROM RankingT;
PARTITION BY Keyword, Day:指定按关键字和日期分组,每组内单独计算排名ROW_NUMBER():给每组内的行生成从1开始的连续编号ORDER BY Asin:定义每组内的排序规则(你可以根据实际需求换成其他字段,比如如果有特定顺序要求的话)
如果需要把计算出的排名更新回原表,可以用JOIN的方式:
UPDATE RankingT t JOIN ( SELECT Keyword, Asin, Day, ROW_NUMBER() OVER (PARTITION BY Keyword, Day ORDER BY Asin) AS new_ranking FROM RankingT ) r ON t.Keyword = r.Keyword AND t.Asin = r.Asin AND t.Day = r.Day SET t.Ranking = r.new_ranking;
方案2:兼容低版本MySQL(5.x)的变量方法
如果你的MySQL版本低于8.0,没法用窗口函数,可以用自定义变量来实现分组排名:
SELECT Keyword, Asin, Day, @ranking := CASE WHEN @prev_keyword = Keyword AND @prev_day = Day THEN @ranking + 1 ELSE 1 END AS Ranking, -- 更新变量为当前行的值,供下一行判断使用 @prev_keyword := Keyword, @prev_day := Day FROM RankingT, -- 初始化变量:排名从0开始,上一组的关键字和日期为空 (SELECT @ranking := 0, @prev_keyword := '', @prev_day := '') AS vars -- 必须按分组字段排序,保证同组的行连续排列 ORDER BY Keyword, Day, Asin;
这个逻辑是:每一行对比当前的Keyword和Day是否和上一行一致,如果一致就排名+1,否则重置为1。注意一定要加上ORDER BY,否则分组逻辑会出错。
同样,如果要更新原表,把上面的查询作为子查询和原表JOIN后更新即可。
用上面两种方法处理后,就能得到你想要的结果表啦!
内容的提问来源于stack exchange,提问作者F T
相关产品推荐
相关产品推荐

