MySQL - 连续交换两列的值

时间:2015-03-06 11:05:51

标签: mysql sql

我正在尝试更正存储两年的表格中的某些数据:

id | start_year | end_year
---|------------|---------
1  |    2001    |   2003
2  |    2008    |   2005
3  |    2004    |   2010
4  |    2012    |   NULL
5  |    2003    |   2004

就像第2行一样,这些年是错误的。如何在start_year > end_year

的行上交换这些列的值

注意:不应交换第4行,其中end_year为NULL。那应该保持不变。

3 个答案:

答案 0 :(得分:9)

MySQL manual中所述:

  

以下语句中的第二个赋值将col2设置为当前(更新的)col1值,而不是原始col1值。结果是col1col2具有相同的值。此行为与标准SQL不同。

UPDATE t1 SET col1 = col1 + 1, col2 = col1;

因此,您无法使用简单的UPDATE命令。相反,您可以执行自联接:

UPDATE myTable old
  JOIN myTable new USING (id)
SET    new.start_year = old.end_year,
       new.end_year = old.start_year
WHERE  old.start_year > old.end_year

答案 1 :(得分:0)

一些数学魔术可以提供帮助:

UPDATE myTable
SET start_year = start_year - end_year,
    end_year   = end_year + start_year,
    start_year = end_year - start_year
WHERE start_year > end_year
  AND end_year IS NOT NULL

备注

我不知道这种更新方法有多可靠。为了获得所需的效果,必须计算表达式,并且必须按查询中显示的顺序完成赋值。如果MySQL决定以不同的顺序计算或分配它们,那么查询将在表格中产生混乱。

摘自the manual

  

单表UPDATE分配通常从左到右进行评估。对于多表更新,无法保证以任何特定顺序执行分配。

从上面的片段中不清楚是否从左到右评估作业。它说"一般"但它没有解释什么是例外。

我使用问题中提供的小样本数据测试了MySQL 5.5.24上的查询,并且它按预期工作。

建议

在运行此查询之前备份您的表。你被警告了!

答案 2 :(得分:-2)

警告,下面的一般ISO / ANSI SQL答案可以在MySQL上运行:

update tablename
  set start_year = end_year,
      end_year = start_year
where start_year > end_year