2012-04-28 32 views
5

Estoy trabajando con una tabla de base de datos MySQL compleja que recopila datos de formulario. He simplificado el diseño de una tabla de ejemplo llama prueba a continuación:ACTUALIZACIÓN MySQL con SUBQUERÍA de la misma tabla

|FormID|FieldName| FieldValue | 
| 1 | city | Houston | 
| 1 | country |  USA  | 
| 2 | city | New York | 
| 2 | country |United States| 
| 3 | property| Bellagio | 
| 3 | price |  120  | 
| 4 | city | New York | 
| 4 |zip code | 12345 | 
| 5 | city | Houston | 
| 5 | country |  US  | 

A través de phpMyAdmin Necesito hacer cambios globales para algunas tablas, específicamente Quiero actualización todos ValorDelCampo entradas a "Estados Unidos de América" ​​con elNombreCampo 'país' que tienen el mismo formid como el NombreCampo 'ciudad' y el ValorDelCampo 'Houston'.

puedo fácilmente pantalla estas entradas con una instrucción SELECT, ya sea usando una sub consulta o mediante el uso de un INNER JOIN:

SELECT FieldValue 
FROM test 
WHERE FormID 
IN (
    SELECT FormID 
    FROM test 
    WHERE FieldName = "city" 
    AND FieldValue = "Houston" 
    ) 
AND FieldName = "country" 

O:

SELECT a.FieldValue 
FROM test a 
INNER JOIN test b ON a.FormID = b.FormID 
WHERE a.FieldName = "country" 
AND b.FieldName = "city" 
AND b.FieldValue = "Houston" 

Sin embargo trato de componer mi ACTUALIZACIÓN instrucción Obtengo algún tipo de error MySQL que indica que no puedo hacer referencia a la misma tabla en una subconsulta o unión interna o unión escenario. Incluso he creado una vista de y traté de hacer referencia a esto en la declaración de actualización, pero no resolvió. ¿Alguien tiene alguna idea de cómo ayudarme?

+0

posible duplicado de [Mysql error 1093 - No se puede especificar la tabla de destino para la actualización en la cláusula FROM] (http://stackoverflow.com/questions/45494/mysql-error- 1093-cant-especifica-tar get-table-for-update-in-from-clause) – Ian

Respuesta

6

Aliasing debe hacer el truco, si estoy entendiendo correctamente:

UPDATE test AS a 
JOIN test AS b ON a.id = b.id 
    SET a.name = 'New Name' 
WHERE a.id = 104; 

¿No es este trabajo para usted?

1

El Hoyle, solución ANSI-SQL sería:

Update test 
Set name = "United States of America" 
Where FormId In (
       Select T1.FormID 
       From test As T1 
       Where T1.FieldName = 'city' 
        And T1.FieldValue = 'Houston' 
       ) 
    And FieldName = 'country' 

La pieza Creo que se echa en falta es que es necesario utilizar un alias en la tabla de la subconsulta.

9

Tiene que usar una tabla temporal, porque no puede actualizar algo que usa para seleccionar. Un exemple simple:

Esto no va a trabajar:

UPDATE mytable p1 SET p1.type= 'OFFER' WHERE p1.parent IN 
    (SELECT p2.id from mytable p2 WHERE p2.actu_id IS NOT NULL); 

Esto hará el trabajo:

UPDATE mytable p1 SET p1.type= 'OFFER' WHERE p1.parent IN 
    (SELECT p2.id from (SELECT * FROM mytable) p2 WHERE p2.actu_id IS NOT NULL); 

"FROM (SELECT * FROM mitabla) p2" creará un duplicado temporal de su tabla, que no se verá afectada por sus actualizaciones

Cuestiones relacionadas