【问题标题】:Resorting a group of rows诉诸一组行
【发布时间】:2021-11-18 16:14:19
【问题描述】:

假设我有下表,排名,

|film_id|user_id|rank|
|-------|-------|----|
|1      |1      |2   |
|2      |1      |3   |
|3      |1      |1   |
|1      |2      |2   |
|2      |2      |1   |
|3      |2      |3   |

然后我删除电影 ID 2

是否有一种 MySQL 方法可以在单个查询中重新排列每个用户的剩余电影,例如:

|film_id|user_id|rank|
|-------|-------|----|
|1      |1      |2   |
|3      |1      |1   |
|1      |2      |1   | <- changed from 2 to 1
|3      |2      |2   | <- changed from 3 to 2

为清楚起见进行编辑:我不确定我是否会准确地将其称为公式,但我想做的只是有一个查询,按其排名顺序加载其余电影,然后以相同的方式重建排名顺序,连续。

也就是说,如果删除一行后,用户的排名是 1,2,4,5,6,我希望它重新构建为从 1(1,2,3,4,5)开始连续.

谢谢!

【问题讨论】:

  • 显而易见的方法是在与之前计算的相同的基础上重新计算排名。这里没有任何迹象表明这是如何完成的。
  • @TangentiallyPerpendicular,抱歉,这似乎与问题无关,但很高兴详细说明。它本身不是计算出来的。它由用户设置。应用程序逻辑按顺序获取一个 film_ids 列表,并根据需要更新排名。在用户排序的情况下,这是一种设置顺序的简单、廉价的方式。在处理删除的情况下,我想知道是否可以更快地处理数据库中的所有细节,因为所需的所有信息都已经在数据库中。
  • 如果您提供计算排名的公式,则完全可以这样做。目前该问题缺少此信息,因此无法回答。
  • @TheImpaler,也许我只是在想它,我不看是一个公式。我想是的。我只想按用户删除一行留下的空白。我用更多信息更新了问题。
  • 你想用新的排名更新表格还是只是一个选择查询?另外,你的MySql是什么版本的?

标签: mysql sorting join sql-update window-functions


【解决方案1】:

将表加入使用ROW_NUMBER()窗口函数重建排名的查询:

UPDATE tablename t1
INNER JOIN (
  SELECT *, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY `rank`) rn
  FROM tablename
) t2 ON t2.film_id = t1.film_id AND t2.user_id = t1.user_id
SET t1.`rank` = t2.rn
WHERE t1.`rank` <> t2.rn; -- actually this in not needed 
                          -- as MySql does not perform the update 
                          -- if the current and new values are the same

请参阅demo

【讨论】:

  • 效果很好!谢谢你。我喜欢这样的解决方案,它可以将处理保持在最有效处理的地方,但我就是想不通。 (我对OVER (PARTITION BY... 子句有一些研究要做,因为我以前没有见过。)
猜你喜欢
  • 2019-10-23
  • 1970-01-01
  • 1970-01-01
  • 2012-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-02
相关资源
最近更新 更多