SQL UPDATE SET una columna para que sea igual a un valor en una tabla relacionada referenciada por una columna diferente?

112

Espero que tenga sentido, déjame explicarlo:

Hay una tabla de datos de seguimiento para un programa de prueba donde cada fila tiene ..

QuestionID y AnswerID (hay una tabla para cada uno). Entonces, debido a un error, hubo un montón de QuestionID configurados en NULL, pero el QuestionID de un AnswerID relacionado está en la tabla de Respuestas.

Entonces, digamos que QuestionID es NULL y AnswerID es 500, si vamos a la tabla de Respuestas y encontramos AnswerID 500, hay una columna con QuestionID que debería haber estado donde está el valor NULL.

Básicamente, quiero configurar cada ID de pregunta NULL para que sea igual al ID de pregunta que se encuentra en la tabla Respuestas en la fila Respuesta del ID de respuesta que se encuentra en la tabla de seguimiento (la misma fila que el ID de pregunta NULO que se está escribiendo).

¿Cómo haría esto?

UPDATE QuestionTrackings
SET QuestionID = (need some select query that will get the QuestionID from the AnswerID in this row)
WHERE QuestionID is NULL AND ... ?

No estoy seguro de cómo podré hacer que asigne el QuestionID al QuestionID del AnswerID correspondiente ...

CloudMeta
fuente
MySQL y Microsoft SQL Server admiten extensiones de la sintaxis SQL para admitir ACTUALIZACIÓN de varias tablas. Otras marcas no lo hacen. No ha dicho qué marca de base de datos está utilizando.
Bill Karwin

Respuestas:

171
update q
set q.QuestionID = a.QuestionID
from QuestionTrackings q
inner join QuestionAnswers a
on q.AnswerID = a.AnswerID
where q.QuestionID is null -- and other conditions you might want

Recomiendo verificar cuál es el conjunto de resultados para actualizar antes de ejecutar la actualización (la misma consulta, solo con una selección):

select *
from QuestionTrackings q
inner join QuestionAnswers a
on q.AnswerID = a.AnswerID
where q.QuestionID is null -- and other conditions you might want

En particular, si cada ID de respuesta tiene definitivamente solo 1 ID de pregunta asociada.

eglasius
fuente
7
No estoy seguro de por qué, pero esto no funciona para mí, sin embargo, esto sí: update QuestionTrackings q inner join QuestionAnswers a on q.AnswerID = a.AnswerID set q.QuestionID = a.QuestionID; parece ser la misma consulta básica en un orden diferente. alguna idea de por qué?
billynoah
2
@billynoah, ORA-00971: falta la palabra clave SET en Oracle
masT
2
Tener un problema con una situación similar en PhpMyAdmin sobre MySQL. En mi caso, las columnas de origen y destino están en la misma tabla, pero la selección de registros se basa en la otra tabla. La versión "SELECT" de la consulta funciona, pero la instrucción UPDTATE arroja un error de sintaxis en "FROM"
2NinerRomeo
3
UPDATE table1 NATURAL JOIN table2 SET table1.col1 = table1.col2 WHERE table2.col3 ="condition"
Superé
¿Es "q" de "actualizar q" en la respuesta un parámetro de consulta literal o es solo su abreviatura para el nombre de una tabla?
Shawn
28

Sin la notación de actualización y unión (no todos los DBMS lo admiten), use:

UPDATE QuestionTrackings
   SET QuestionID = (SELECT QuestionID
                        FROM AnswerTrackings
                        WHERE AnswerTrackings.AnswerID = QuestionTrackings.AnswerID)
   WHERE QuestionID IS NULL
     AND EXISTS(SELECT QuestionID
                        FROM AnswerTrackings
                        WHERE AnswerTrackings.AnswerID = QuestionTrackings.AnswerID)

A menudo, en una consulta como esta, necesita calificar la cláusula WHERE con una cláusula EXISTS que contiene la subconsulta. Esto evita que la ACTUALIZACIÓN pisotee las filas donde no hay coincidencia (por lo general, anula todos los valores). En este caso, dado que una ID de pregunta faltante cambiaría NULL a NULL, podría decirse que no importa.

Jonathan Leffler
fuente
Este método funcionó para mí en Oracle 12c (donde falló el método de actualización-unión).
shwartz
16

No sé si se ha encontrado con el mismo problema que yo en MySQL Workbench, pero ejecutar la consulta con el INNER JOINdespués de la FROMdeclaración no funcionó para mí. No pude ejecutar la consulta porque el programa se quejó de la FROMdeclaración.

Entonces, para que la consulta funcione, la cambié a

UPDATE table1 INNER JOIN table2 on table1.column1 = table2.column1
SET table1.column2 = table2.column4
WHERE table1.column3 = 'randomCondition';

en vez de

UPDATE a
FROM table1 a INNER JOIN table2 b on a.column1 = b.column1
SET a.column2 = b.column4
WHERE a.column3 = 'randomCondition';

Supongo que mi solución es la sintaxis correcta para MySQL.

AxeEffect
fuente
Sí, parece que para Mysql, JOIN se considera parte de la parte 'table_references' de una consulta. MySQL Join
AWP
12
UPDATE
    "QuestionTrackings"
SET
    "QuestionID" = (SELECT "QuestionID" FROM "Answers" WHERE "AnswerID"="QuestionTrackings"."AnswerID")
WHERE
    "QuestionID" is NULL
AND ...
Milen A. Radev
fuente
1
Trabajó en Oracle para mí. La respuesta de @ eglasius no lo hizo.
Lombas
7

Tenía la misma pregunta. Aquí hay una solución de trabajo que es similar a la de eglasius. Estoy usando postgresql.

UPDATE QuestionTrackings
SET QuestionID = a.QuestionID
FROM QuestionTrackings q, QuestionAnswers a
WHERE q.QuestionID IS NULL

Se queja si se usó q en lugar del nombre de la tabla en la línea 1, y nada debe preceder a QuestionID en la línea 2.

Mentes de iluminación
fuente
3
 select p.post_title,m.meta_value sale_price ,n.meta_value   regular_price
    from  wp_postmeta m 
    inner join wp_postmeta n
      on m.post_id  = n.post_id
    inner join wp_posts p
      ON m.post_id=p.id 
    and m.meta_key = '_sale_price'
    and  n.meta_key = '_regular_price'
     AND p.post_type = 'product';



 update  wp_postmeta m 
inner join wp_postmeta n
  on m.post_id  = n.post_id
inner join wp_posts p
  ON m.post_id=p.id 
and m.meta_key = '_sale_price'
and  n.meta_key = '_regular_price'
 AND p.post_type = 'product'
 set m.meta_value = n.meta_value;
Franco
fuente
3

Para Mysql puede utilizar esta consulta

ACTUALIZAR table1 a, table2 b SET a.coloumn = b.coloumn DONDE a.id = b.id

Samir Patel
fuente
1

Actualizar los datos de la segunda tabla en la primera tabla debe unirse internamente antes de SET:

`UPDATE `table1` INNER JOIN `table2` ON `table2`.`id`=`table1`.`id` SET `table1`.`name`=`table2`.`name`, `table1`.`template`=`table2`.`template`;
Santosh Singh
fuente
1

a continuación funciona para mysql

update table1 INNER JOIN table2 on table1.col1 =  table2.col1
set table1.col1 =  table2.col2
Pravin
fuente
0

Creo que esto debería funcionar.

UPDATE QuestionTrackings
SET QuestionID = (SELECT QuestionID
                  FROM AnswerTrackings
                  WHERE AnswerTrackings.AnswerID = QuestionTrackings.AnswerID)
WHERE QuestionID IS NULL
AND AnswerID IS NOT NULL;
Novato
fuente