使用MySQL有效地将升序位置保存到行数

时间:2012-03-29 09:57:33

标签: mysql sql sql-update

我正在寻找更新where和order by语句选择的行数的最有效方法,以便将位置1到n保存到这些行。对于排序字段中的相同值,应该有相同的位置,但是必须跳过下一个位置。

ID, catagory_id, price, position
1,  1,           19.99, NULL
2,  2,            9.99, NULL
3,  1,            9.99, NULL
4,  1,            9.99, NULL
5,  1,            2.99, NULL

UPDATE stuff SET position=XXX WHERE category_id = 1 ORDER BY price ASC

ID, catagory_id, price, position
1,  1,           19.99, 4
2,  2,            9.99, NULL
3,  1,            9.99, 2
4,  1,            9.99, 2
5,  1,            2.99, 1

请注意,position=2设置了两次,因此省略position=3

单个SQL查询是否可以实现?我不想为每一行发布更新声明,因为我将不得不每天更新数百万。

没有相同的职位,我使用过:

  SELECT @row:=0;
  UPDATE offers SET position = (@row:=@row+1) WHERE category_id = 1 ORDER BY price ASC;

1 个答案:

答案 0 :(得分:0)

你的问题不明确。据我所知,您希望使用给定类别中特定行的等级填充位置列。

[1]初始化:

SELECT @pos:=0, @prev_price:=-1.0, @omitted:=0;

[2]使用此查询获取所需的位置编号:

SELECT id, IF(price > @prev_price, @pos:=@omitted+@pos+1, @pos) AS position, IF(@prev_price = price, @omitted:=@omitted+1, @omitted:=0), @prev_price:=price FROM offers WHERE category_id = 1 ORDER BY price ASC;

[3]现在结果设置为INSERT .... ON DUPLICATE KEY UPDATE

INSERT INTO offers (id, position) SELECT A.id, A.position FROM (SELECT id, IF(price > @prev_price, @pos:=@omitted+@pos+1, @pos) AS position, IF(@prev_price = price, @omitted:=@omitted+1, @omitted:=0), @prev_price:=price FROM offers WHERE category_id=1 ORDER BY price ASC) AS A ON DUPLICATE KEY UPDATE position = A.position;