重新排序mysql中的项目

时间:2019-02-11 05:37:31

标签: mysql

我有一个MySQL表,该表包含以下列:(ID,位置等)。位置表示排序顺序。如何重新排列项目的位置。例如,如果我想将第3位的商品重新排列到第5位,反之亦然,该如何实现?

以下是一些示例数据:

id  position name
==  ======== ======
1       5     Fred
2       3     Wilma
3       1     Betty
4       2     Barney
5       4     Pebbles

因此,如果我做select * from customer order by position,我会得到:

id position name
== ======== =======
3      1     Betty
4      2     Barney
2      3     Wilma
5      4     Pebbles
1      5     Fred

然后我可能想将Fred在列表中上移,说到位置3。然后,我希望列表看起来像这样:

id position name
== ======== =======
3      1     Betty
4      2     Barney
1      3     Fred
2      4     Wilma
5      5     Pebbles

我的问题是,如何在列表中上下移动项目并获得相应的位置调整?

我认为确保没有丢失或重复的职位编号也很重要。

3 个答案:

答案 0 :(得分:1)

在此UPDATE示例中,必须设置pos_from和pos_to。

pos_from的位置将更改为pos_to。
其他需要上移或下移的对象将相应地用+1或-1进行校正。

pos_from可以高于或低于pos_to。

create table bedrock (
  id int primary key auto_increment, 
  position int not null, 
  name varchar(30) not null
);
insert into  bedrock (position, name) values
(5, 'Fred'),
(3, 'Wilma'),
(1, 'Betty'),
(2, 'Barney'),
(4, 'Pebbles');
select * from bedrock order by position;
id | position | name   
-: | -------: | :------
 3 |        1 | Betty  
 4 |        2 | Barney 
 2 |        3 | Wilma  
 5 |        4 | Pebbles
 1 |        5 | Fred   
update bedrock
join
(
  select pos_from, pos_to, 
  case when pos_to > pos_from then pos_from else pos_to end as pos_min,
  case when pos_to > pos_from then pos_to else pos_from end as pos_max,
  case when pos_to > pos_from then -1 else 1 end as pos_delta
  from (
    select 
    5 as pos_from, 
    3 as pos_to
  ) q1
) q2 on position between pos_min and pos_max
set position = case 
               when position = pos_from 
               then pos_to 
               else position + pos_delta 
               end;
select * from bedrock order by position;
id | position | name   
-: | -------: | :------
 3 |        1 | Betty  
 4 |        2 | Barney 
 1 |        3 | Fred   
 2 |        4 | Wilma  
 5 |        5 | Pebbles

db <>提琴here

答案 1 :(得分:0)

您可以创建一个存储过程来更新位置:

DELIMITER //
CREATE PROCEDURE simpleproc (IN param1 INT, IN param2 INT)
BEGIN
   UPDATE sampleTable SET position = position + 1 WHERE position >= param2;
   UPDATE sampleTable SET position = param2 WHERE id = param1;
END;//
DELIMITER ;

只需确保未将位置设置为主键,我知道您希望它唯一即可;但这会导致程序出现问题。

顺便说一句,param1是要更新的记录ID,param2是要设置的位置。

enter image description here enter image description here enter image description here

它很好用。

答案 2 :(得分:-1)

我希望,您希望在下面的查询中看到此信息。

select *,case when position = 3 then 5 when position = 5 then 3 else position end as new_position from customer order by new_position