2011-08-07 92 views
10

我试图在单个查询中更新一组记录(boolean字段)(如果可能的话)。一个查询中的MySQL更新条件(更新,设置和CASE)

输入来自分页的无线电控制,因此给定的POST将具有页面的值,其值为truefalse值。

我试图去这个方向:

UPDATE my_table 
    SET field = CASE 
     WHEN id IN (/* true ids */) THEN TRUE 
     WHEN id IN (/* false ids */) THEN FALSE 
    END 

,但是这导致了“真正的ID”行正在更新true,并ALL其他行进行了更新,以false

我假设我已经犯了一些严重的语法错误,或者我正在接近这个错误。

对解决方案有何想法?

+0

可能重复http://stackoverflow.com/questions/6734231/mysql-更新案例帮助) – nawfal

回答

18

难道你没有忘记在病例陈述中做“否”吗?

UPDATE my_table 
    SET field = CASE 
     WHEN id IN (/* true ids */) THEN TRUE 
     WHEN id IN (/* false ids */) THEN FALSE 
     ELSE field=field 
    END 

没有ELSE,我假设评估链停在最后一个WHEN并执行该更新。此外,您不限制您尝试更新的行;如果你不做ELSE,你至少应该告诉更新只更新你想要的行,而不是所有的行(如你所做的那样)。看看下面的WHERE子句:

UPDATE my_table 
     SET field = CASE 
      WHEN id IN (/* true ids */) THEN TRUE 
      WHEN id IN (/* false ids */) THEN FALSE 
     END 
    WHERE id in (true ids + false_ids) 
+0

谢谢@Icarus - 你发布的第二个解决方案是完美的。虽然第一个工作当然是,MySQL匹配表中的每一行;这似乎很容易导致在较大的表(* 10^6行或更多*)中导致性能损失,尽管它只是实际更新已更改的行。你能对此有所了解吗? (*所有目标ID联盟的条件是一个足够干净的解决方案,但我只是好奇*) – Dan

+1

@TomcatExodus:我不知道我很理解你的问题,但是,一般来说,如果你有一个更新没有数据库引擎几乎肯定必须执行表扫描并且会损害性能,特别是在大型表中。所以是的,那里的where子句应该更快,但只有id列也是索引。如果不是,则表扫描是不可避免的。 – Icarus

+0

好的@Icarus - 这就是我的意思,'id'列被索引。我指的是输出流;如果没有'WHERE'子句,我会得到几千行匹配的行,但只有少数行受到影响。被匹配的数千个是我想避免的全表扫描,并且通过应用'WHERE'子句避免了*,*仅仅指定了真/假ID的联合。只是想澄清一下。谢谢! – Dan

4

就可以避免字段=场

update my_table 
    set field = case 
     when id in (....) then true 
     when id in (...) then false 
     else field 
    end 
的[MySQL的更新情况说明](
+0

谢谢@nick rulez - “field = field”乍一看也很奇怪(* field = field = field * *) – Dan