我有一个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
我的问题是,如何在列表中上下移动项目并获得相应的位置调整?
我认为确保没有丢失或重复的职位编号也很重要。
答案 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是要设置的位置。
它很好用。
答案 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