2011-08-07 8 views
10

Estoy tratando de actualizar un conjunto de registros (boolean campos) en una sola consulta si es posible.Condiciones de actualización de MySQL en una consulta (ACTUALIZACIÓN, CONFIGURACIÓN Y CASE)

La entrada proviene de controles de radio paginados, por lo que un POST dado tendrá los ID de la página con un valor de true o false.

yo estaba tratando de ir a esta dirección:

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

Pero esto resultó en las filas "verdadera" id están actualizando para true y TODAS otras filas se actualizaron a false.

Supongo que he cometido un error sintáctico grave, o tal vez que me estoy acercando a esto incorrectamente.

¿Alguna idea de una solución?

+0

posible duplicado de [caso actualización de ayuda MySQL] (http://stackoverflow.com/questions/6734231/mysql- update-case-help) – nawfal

Respuesta

18

¿No se olvidó de hacer un "ELSE" en la declaración del caso?

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

Sin el ELSE, supongo que la cadena de evaluación se detiene en el último WHEN y ejecuta esa actualización. Además, no está limitando las filas que está tratando de actualizar; si no hace el ELSE, al menos debe decirle a la actualización que solo actualice las filas que desea y no todas las filas (como lo hace). Mira la cláusula WHERE a continuación:

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

Gracias @Icarus: la segunda solución que publicaste es perfecta. Mientras que el primero funciona, por supuesto, MySQL coincide con cada fila en la tabla; parece que puede causar pérdida de rendimiento en tablas más grandes (* 10^6 filas o más *) a pesar de que solo actualiza las filas que han cambiado. ¿Puedes arrojar algo de luz sobre esto? (* la condición de una unión de todas las ID identificadas es una solución suficientemente limpia, pero solo tengo curiosidad *) – Dan

+1

@TomcatExodus: no estoy seguro de haber entendido bien tu pregunta, pero, en general, si tienes una actualización sin donde cláusula el motor de la base de datos casi seguramente tendrá que realizar un escaneo de tabla y perjudicará el rendimiento, especialmente en las tablas grandes. Así que sí, tener la cláusula where allí debería ser más rápida, pero solo si la columna id también es un índice. Si no es así, la exploración de la tabla es inevitable. – Icarus

+0

Ok @Icarus: eso es lo que quise decir, la columna 'id' está indexada. Me refería a la secuencia de salida; sin la cláusula 'WHERE', obtengo varios miles de filas coincidentes, pero solo unos pocos se ven afectados. Los miles que coinciden es la exploración completa de la tabla que me gustaría evitar, y * se * evita al aplicar una cláusula 'WHERE', que especifica solo una unión de identificadores de verdadero/falso. Solo quería una aclaración. ¡Gracias! – Dan

4

Usted puede evitar campo = campo

update my_table 
    set field = case 
     when id in (....) then true 
     when id in (...) then false 
     else field 
    end 
+0

Gracias @nick rulez - El 'campo = campo' también parecía extraño a primera vista (* campo = campo = campo? *) – Dan

Cuestiones relacionadas