在MySql中切换两行的id号

时间:2011-07-08 20:27:25

标签: php mysql sql database

我正在尝试使用php在mysql中切换两行的id - 我读的越多,我就越困惑。似乎有很多相互矛盾的信息。有没有人得到明确的答案。

例如,在初始状态下,我的行是

1-Peter-22-germany
2-mary-16-iceland
3-tom-29-france
4-michael-34-greece

然后我想交换第2行和第3行的id,以便它看起来像这样

1-Peter-22-germany
3-mary-16-iceland
2-tom-29-france
4-michael-34-greece

所以,如果我然后通过id订购它我会

1-Peter-22-germany
2-tom-29-france
3-mary-16-iceland
4-michael-34-greece

5 个答案:

答案 0 :(得分:12)

UPDATE yourtable SET id=IF(id=2, 3, 2) where id in(2,3)

可能会做到这一点,但这是一个坏主意 - 操纵/重新分配主键值绝不是一个好主意。

如果此操作失败,那么是因为重复密钥违规(最有可能),并且您需要暂时将其中一个ID重新分配给其他唯一值,以便在重新分配时不会发生冲突正在进行中 - 这将要求您至少使用两个查询。

答案 1 :(得分:11)

如果ID是主键,那么您不想更改它/能够更改它。如果这只是用于排序,我建议制作一个“订单”列,是一个整数并对其进行排序。表模式可以很好地看到这一点,但到目前为止这是我的建议。

如果在输入行时自动创建ID,那么这个想法就是一个更大的问题。但是,现在我只是在猜测,因为我不知道你的表模式。

以下是关于主键的一些标准建议:除了唯一标识符外,不要将它们视为任何内容。

答案 2 :(得分:1)

我很想知道为什么你需要永久性的。我能想到的唯一事情是你可以改变事件的明显顺序。

正如其他人所说,ID通常是主键并且是自动编号的,这使得它很难,但实现这一点的显而易见的方法是将两个项目中的所有字段数据收集到一个数组中,并使用它来更新每个记录。来自另一个的价值观。

答案 3 :(得分:0)

你需要SORT BY一些东西。我们需要查看您的表架构。

答案 4 :(得分:0)

使用存储过程和临时表更轻松地实现交换ID:

CREATE PROCEDURE `swapIDs`(aTable varchar(64),aID1 int(11),aID2 int(11))
BEGIN
 drop temporary table if exists swapIDsTable;
 SET @s = concat('create temporary table swapIDsTable like ',aTable); PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt;
 SET @s = concat('insert into swapIDsTable select * from ',aTable,' where id=',aID1);  PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt;
 SET @s = concat('delete from ', aTable, ' where id=',aID1); PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt;
 SET @s = concat('update ', aTable, ' set id=',aID1,' where id=',aID2); PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt;
 SET @s = concat('update swapIDsTable set id=',aID2,' where id=',aID1); PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt;
 SET @s = concat('insert into ', aTable,' select * from swapIDsTable where id=',aID2); PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt;
 drop temporary table if exists swapIDsTable;
END |

但是想象一下,你已经转移了由客户端(应用程序)端的另一个用户更新的id,并且只有线索(用于应用程序)才能了解哪个raw更新是ID。那将是噩梦。

因此,此程序在单用户使用中可以100%有用。

另一种方法是更新(交换)两行之间的所有列值:

UPDATE targetTable tab1, targetTable tab2 SET tab1.<colX>=tab2.<colX>, tab2.<colX>=tab1.<colX>  where tab1.id=<id1> and tab2.id=<id2>;

仍然需要一些同步机制。