UPDATE中每个SET命令的SQL - WHERE子句?

时间:2009-09-14 12:00:18

标签: sql sql-update

我正在尝试在PHP中创建一个SQL查询来更新表。 是否可以为每个受影响的行设置不同的WHERE子句?

例如:

UPDATE table 
SET val=X WHERE someproperty = 1,
SET val=Y WHERE someproperty = 2

等?

任何帮助表示赞赏。感谢

5 个答案:

答案 0 :(得分:14)

是的,您可以使用CASE声明。

UPDATE table
SET val = CASE someproperty  
           WHEN 1 THEN x 
           WHEN 2 THEN y
           ....
          ELSE
           val
          END

现在,有人担心,与几个CASE语句相比,一个UPDATE语句的可读性较差。这里有一个有效的论点。例如,当正在更新1000行时,使用多个UPDATE语句而不是1000个不同条件对单个CASE感觉并且看起来更好看。

但是,有时CASE声明更合适。例如,如果您基于某些特征更新行,比如表的字段值的偶数或奇数性质,则CASE语句是一种非常简洁且可维护的方式来更新表中的行而不具有诉诸于大量UPDATE语句,这些语句都具有特定类型的逻辑。以此为例:

UPDATE table
SET val = CASE MOD(someproperty, 2)  
           WHEN 0 THEN x 
           WHEN 1 THEN y
          END

此表达式采用someproperty的模数,当为0(偶数)时,将值x赋值给val,当为1(奇数)时,将值y赋给val。此语句更新的数据量越大,与多个UPDATE语句相比,它就越清晰。

简而言之,CASE语句有时与UPDATE语句一样可读/可维护。这完全取决于你试图用它们做什么。

编辑:添加ELSE子句是额外安全的。 OP可能只对更新特定行感兴趣,因此其余部分应保持在UPDATE之前。

编辑:添加了一个方案,其中CASE语句比多个UPDATE语句更有效。

答案 1 :(得分:9)

任何SQL语句都不能有多个WHERE子句,但是您可以使用CASE语句来完成您尝试执行的操作。您拥有的另一个选项是执行多个UPDATE语句。

以下是使用CASE语句的示例:

UPDATE table
SET val = (
    CASE someproperty
        WHEN 1 THEN X
        WHEN 2 THEN Y
        ELSE val
    END
);

以下是使用多个UPDATE语句的示例:

UPDATE table SET val=X WHERE someproperty = 1;
UPDATE table SET val=Y WHERE someproperty = 2;

答案 2 :(得分:2)

不。进行两次更新:

UPDATE table SET val=X WHERE someproperty = 1;
UPDATE table SET val=Y WHERE someproperty = 2;

第二个想法,你可以使用子查询或案例陈述......

UPDATE table SET val= ( case when someproperty = 1 then X when someproperty = 2 then Y else val END )

您可能需要制作如下的子查询:

UPDATE table t1 SET val = ( select CASE when someproperty = 1 then X when someproperty = 2 then Y ELSE val END from table t2 where t1.primarykey = t2.primary key )

答案 3 :(得分:1)

UPDATE TABLE
SET VAL CASE SOMEPROPERTY WHEN 1 THEN X WHEN 2 THEN Y END

答案 4 :(得分:0)

紧凑且易于扩展的方式:

UPDATE table1 SET val=ELT(FIND_IN_SET(someproperty, '1, 2'), X, Y);

以这种方式进行查询:

$condition = array(1, 2);
$newvals = array('X', 'Y');
$query = "UPDATE table1 SET val=ELT(FIND_IN_SET(someproperty, '". implode(',', $condition). "', ". implode(', ', $newvals). ")";

如果处理字符串值,请使用prepare查询以避免SQL语法错误。