18

假设一个fruits看起来像这样的表:

------------------------------------------
| id |    name    |   color   | calories |
------------------------------------------
| 1  | apple      | red       | 20       |
| 2  | orange     | orange    | 10       |
| 3  | grapes     | green     | 5        |
| 4  | bananas    | yellow    | 15       |
| 5  | plum       | purple    | 25       |
------------------------------------------

如何将一行的值与另一行交换,保持 id 号不变?

例子:

SWAP ROW WITH ID "5" WITH ROW WITH ID "2"

结果:

------------------------------------------
| id |    name    |   color   | calories |
------------------------------------------
| 1  | apple      | red       | 20       |
| 2  | plum       | purple    | 25       |
| 3  | grapes     | green     | 5        |
| 4  | bananas    | yellow    | 15       |
| 5  | orange     | orange    | 10       |
------------------------------------------

请注意,除了 id 之外,所有值都是完整的。我需要使用非常大的值列表来执行此操作,因此我需要一个单行代码,或者最多需要一个不需要创建临时表之类的东西。

注意:id 是唯一的

谢谢

4

4 回答 4

15

您可以使用连接不等式来排列要交换的行:

update fruit a
 inner join fruit b on a.id <> b.id
   set a.color = b.color,
       a.name = b.name,
       a.calories = b.calories
 where a.id in (2,5) and b.id in (2,5)

http://sqlfiddle.com/#!18/27318a/5

于 2013-07-02T19:33:14.850 回答
8

由于 ID 是唯一的,很难只交换 ID,交换列内容更容易。像这样的查询可能是您需要的:

UPDATE
  yourtable t1 INNER JOIN yourtable t2
  ON (t1.id, t2.id) IN ((1,5),(5,1))
SET
  t1.color = t2.color,
  t1.name = t2.name,
  t1.calories = t2.calories

在此处查看小提琴。

于 2013-07-02T19:14:45.253 回答
0

如果您的操作是基于ID的,并且您想要交换整行,那么交换UNIQUE ID的一种奇特方式是从 1 开始对它们进行编号,并使用 0 作为临时值。

执行此操作的另一种方法是使用无符号列,并使用指定值(即:-1)作为临时值。我不会真的推荐后者,因为我们用这种方法实际上是在浪费空间。有关详细信息,请参阅http://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.html 。

于 2014-09-26T19:31:41.443 回答
0

这是一种临时存储值的方法,而无需在水果表中使用临时表或虚拟行:

SELECT name, color, calories FROM fruit WHERE id = 2 INTO @name, @color, @calories;

UPDATE fruit AS f1, fruit AS f2
SET
 f1.name = f2.name, f2.name = @name,
 f1.color = f2.color, f2.color = @color,
 f1.calories = f2.calories, f2.calories = @calories
WHERE (f1.id, f2.id) = (2, 5);

这是另一个使用虚拟 id 值的解决方案:

UPDATE fruit SET id = 0 WHERE id = 5;
UPDATE fruit SET id = 5 WHERE id = 2;
UPDATE fruit SET id = 2 WHERE id = 0;
于 2013-07-02T19:24:01.043 回答