2011-07-13 7 views
16

Tengo una tabla 'respuestas' con una columna de índice 'problem_id' indexada, una columna entera 'times_chosen' y una columna 'option' que es una varchar. Actualmente, los únicos valores para la columna 'opción' son 'A', 'B', 'C' y 'D', aunque pueden ampliarse más adelante. Quiero incrementar en uno los valores de 'times_chosen' de muchas (50-100) respuestas, cuando conozco el id_itio y la opción de cada uno de ellos.Hacer un DONDE EN en varias columnas en Postgresql

por eso es necesario una consulta que es algo así como:

UPDATE answers 
SET times_chosen = times_chosen + 1 
WHERE (problem_id, option) IN ((4509, 'B'), (622, 'C'), (1066, 'D'), (4059, 'A'), (4740, 'A')...) 

Es esto posible?

+2

Debería, al menos creo que sería en MySQL y MSSQL. ¿Lo has probado? Puedes probarlo con 'SET times_chosen = times_chosen' – Dirk

+0

¡Oh, vaya, realmente funciona, tal como lo escribí! ¡Incluso usa el índice! Gracias Dirk: si solo copias tu respuesta a continuación como respuesta, me complacerá aceptarla. – PreciousBodilyFluids

+0

heh, no sabía que era una sintaxis válida. Eso es útil = D –

Respuesta

8

Se debe, por lo menos yo lo he hecho antes en otras LSQ.

¿Lo has probado? Puede probarlo con SET times_chosen = times_chosen

+0

Funciona muy bien, gracias – Udi

0

Probablemente se esté buscando la sintaxis de estilo

SELECT * FROM foo, bar WHERE foo.bob = "NaN" AND bar.alice = "Kentucky"; 

. Esencialmente, utiliza tablename.rowname para especificar qué campo individual está buscando. Con el fin de alinear todo correctamente, se agrega cláusulas WHERE que hacen que las claves primarias de partido:

...WHERE foo.primarykey = bar.primarykey 

o similar. Haría bien en buscar uniones internas.

17

Usted puede unirse contra una tabla virtual de clases:

SELECT * FROM answers 
JOIN (VALUES (4509, 'B'), (622, 'C'), (1066, 'D'), (4059, 'A'), (4740, 'A')) 
    AS t (p,o) 
ON p = problem_id AND o = option 

se puede hacer algo similar con UPDATE.

+0

Agradable y genial ... –

3

Usted puede hacer esto si lanzas los datos a un array primero:

UPDATE answers 
SET times_chosen = times_chosen + 1 
WHERE ARRAY[problem_id::VARCHAR,option] IN ('{4509,B}', '{622,C}', ...) 

Sin embargo, esto va a ser muy ineficiente, ya que no puede utilizar índices. El uso de un JOIN según lo sugerido por @Frank Farmer es una solución mucho mejor:

UPDATE answers a 
SET times_chosen = times_chosen + 1 
FROM (VALUES (4509,'B'), (622,'C') ...) AS x (id,o) 
    WHERE x.id=a.problem_id AND x.o=a.option; 
Cuestiones relacionadas