MySQL - 具有可变增量的递归重新排序算法/ UPDATE

时间:2014-12-10 12:46:16

标签: mysql sql recursive-query

对于那种毫无意义的标题感到抱歉,但我无法想出一个更合适的标题。


我有一个 MySQL表,如下所示:

SELECT * FROM `table`

+----+-----------+----------+-------+
| id | dimension | order_by | value |
+----+-----------+----------+-------+
|  1 |     1     |     1    |  1st  |
|  2 |     1     |    100   |  3rd  |
|  3 |     2     |    300   |  5th  |
|  4 |     3     |    999   |  6th  |
|  5 |     1     |     2    |  2nd  |
|  6 |     2     |     1    |  4th  |
+----+-----------+----------+-------+

我列出了dimension(第一个)和order_by(第二个)排序的所有条目,如下所示:

SELECT * FROM `table` ORDER BY `dimension`, `order_by`

+----+-----------+----------+-------+
| id | dimension | order_by | value |
+----+-----------+----------+-------+
|  1 |     1     |     1    |  1st  |
|  5 |     1     |     2    |  2nd  |
|  2 |     1     |    100   |  3rd  |
|  6 |     2     |     1    |  4th  |
|  3 |     2     |    300   |  5th  |
|  4 |     3     |    999   |  6th  |
+----+-----------+----------+-------+

现在我想编写一个函数,只需一个order_by查询即可重新排列update,以使其看起来像这样:

SELECT * FROM `table` ORDER BY `dimension`, `order_by`

+----+-----------+----------+-------+
| id | dimension | order_by | value |
+----+-----------+----------+-------+
|  1 |     1     |     1    |  1st  |
|  5 |     1     |     2    |  2nd  |
|  2 |     1     |     3    |  3rd  |
|  6 |     2     |     1    |  4th  |
|  3 |     2     |     2    |  5th  |
|  4 |     3     |     1    |  6th  |
+----+-----------+----------+-------+

到目前为止我得到了什么(不幸的是,它并没有开始为每个维度重新计算):

UPDATE `table` AS `l`
JOIN (SELECT @i=1 FROM `table`) AS `i`
SET `order_by` = @i:=i

现在,我的问题是:是否可以只使用一个UPDATE查询来执行此操作?

1 个答案:

答案 0 :(得分:2)

你必须引入另一个包含前一行值的变量。

UPDATE Table1 t
INNER JOIN (
  SELECT
  id, /*your primary key I assume*/
  @new_ob:=if(@prev != dimension, 1, @new_ob + 1) as new_ob,
  @prev := dimension /*In this line, the value of the current row is assigned. In the previous line, the variable still holds the value of the previous row*/
  FROM
  Table1
  , (SELECT @prev := null, @new_ob := 0) var_init_subquery
  ORDER BY dimension, order_by
) st ON t.id = st.id
SET t.order_by = st.new_ob;