¿Cómo puedo hacer una instrucción UPDATE con JOIN en SQL?

Necesito actualizar esta tabla en SQL Server 2005 con datos de su tabla ‘principal’, ver a continuación:

venta

 id (int) udid (int) assid (int) 

ud

 id (int) assid (int) 

sale.assid contiene el valor correcto para actualizar ud.assid .

¿Qué consulta hará esto? Estoy pensando en join pero no estoy seguro de si es posible.

La syntax depende estrictamente de qué SQL DBMS estás usando. Aquí hay algunas maneras de hacerlo en ANSI / ISO (también debería funcionar en cualquier SQL DBMS), MySQL, SQL Server y Oracle. Tenga en cuenta que mi método ANSI / ISO sugerido suele ser mucho más lento que los otros dos métodos, pero si está utilizando un DBMS SQL distinto de MySQL, SQL Server u Oracle, entonces puede ser el único camino a seguir (por ejemplo, si su SQL DBMS no es compatible con MERGE ):

ANSI / ISO:

 update ud set assid = ( select sale.assid from sale where sale.udid = ud.id ) where exists ( select * from sale where sale.udid = ud.id ); 

MySQL:

 update ud u inner join sale s on u.id = s.udid set u.assid = s.assid 

Servidor SQL:

 update u set u.assid = s.assid from ud u inner join sale s on u.id = s.udid 

Oráculo:

 update (select u.assid as new_assid, s.assid as old_assid from ud u inner join sale s on u.id = s.udid) up set up.new_assid = up.old_assid 

SQLite:

 update ud set assid = ( select sale.assid from sale where sale.udid = ud.id ) where RowID in ( select RowID from ud where sale.udid = ud.id ); 

Esto debería funcionar en SQL Server:

 update ud set assid = sale.assid from sale where sale.udid = id 

postgres

 UPDATE table1 SET COLUMN = value FROM table2, table3 WHERE table1.column_id = table2.id AND table1.column_id = table3.id AND table1.COLUMN = value AND table2.COLUMN = value AND table3.COLUMN = value 

Un enfoque SQL estándar sería

 UPDATE ud SET assid = (SELECT assid FROM sale s WHERE ud.id=s.id) 

En SQL Server puedes usar un join

 UPDATE ud SET assid = s.assid FROM ud u JOIN sale s ON u.id=s.id 

PostgreSQL :

 CREATE TABLE ud (id integer, assid integer); CREATE TABLE sales (id integer, udid integer, assid integer); UPDATE ud SET assid = sales.assid FROM sales WHERE sales.id = ud.id; 

Consulta de actualización simplificada usando JOIN -ing en varias tablas.

  UPDATE first_table ft JOIN second_table st ON st.some_id = ft.some_id JOIN third_table tt ON tt.some_id = st.some_id ..... SET ft.some_column = some_value WHERE ft.some_column = 123456 AND st.some_column = 123456 

Nota : first_table, second_table, third_table y some_column como 123456 son nombres de tablas de demostración, nombres de columnas e ID. Reemplácelos con los nombres válidos.

Otro ejemplo de por qué SQL no es realmente portátil.

Para MySQL sería:

 update ud, sale set ud.assid = sale.assid where sale.udid = ud.id; 

Para obtener más información, lea la actualización de varias tablas: http://dev.mysql.com/doc/refman/5.0/en/update.html

 UPDATE [LOW_PRIORITY] [IGNORE] table_references SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ... [WHERE where_condition] 

Teradata Aster ofrece otra forma interesante de cómo lograr el objective:

 MERGE INTO ud --what trable should be updated USING sale -- from what table/relation update info should be taken ON ud.id = sale.udid --join condition WHEN MATCHED THEN UPDATE SET ud.assid = sale.assid; -- how to update 

Estaba pensando que el SQL-Server uno en la publicación superior funcionaría para Sybase ya que ambos son T-SQL pero desafortunadamente no.

Para Sybase, encontré que la actualización debe estar sobre la mesa, no el alias:

 update ud set u.assid = s.assid from ud u inner join sale s on u.id = s.udid 

La siguiente statement con la palabra clave FROM se usa para actualizar varias filas con una combinación

 UPDATE users set users.DivisionId=divisions.DivisionId from divisions join users on divisions.Name=users.Division 
 UPDATE tblAppraisalBasicData SET tblAppraisalBasicData.ISCbo=1 FROM tblAppraisalBasicData SI INNER JOIN aaa_test RAN ON SI.EmpID = RAN.ID 

Y en MS ACCESS:

 UPDATE ud INNER JOIN sale ON ud.id = sale.udid SET ud.assid = sale.assid; 

MySQL

Obtendrá el mejor rendimiento si olvida la cláusula where y coloca todas las condiciones en la expresión ON.

Creo que esto se debe a que la consulta primero tiene que unirse a las tablas y luego ejecuta la cláusula where sobre eso, de modo que si puede reducir lo que se requiere para unirse, esa es la forma más rápida de obtener los resultados / hacer la udpate.

Ejemplo

Guión

Tienes una tabla de usuarios. Pueden iniciar sesión usando su nombre de usuario o correo electrónico o número de cuenta. Estas cuentas pueden estar activas (1) o inactivas (0). Esta tabla tiene 50000 filas

A continuación, tiene una tabla de usuarios para deshabilitar de una sola vez porque descubre que todos han hecho algo malo. Sin embargo, esta tabla tiene una columna con nombres de usuario, correos electrónicos y números de cuenta mezclados. También tiene un indicador “has_run” que necesita establecerse en 1 (verdadero) cuando se ha ejecutado

Consulta

 UPDATE users User INNER JOIN blacklist_users BlacklistUser ON ( User.username = BlacklistUser.account_ref OR User.email = BlacklistedUser.account_ref OR User.phone_number = BlacklistUser.account_ref AND User.is_active = 1 AND BlacklistUser.has_run = 0 ) SET User.is_active = 0, BlacklistUser.has_run = 1; 

Razonamiento

Si tuviéramos que unirnos solo a las condiciones de OR, básicamente sería necesario verificar cada fila 4 veces para ver si se uniera, y potencialmente devolver muchas más filas. Sin embargo, al darle más condiciones, puede “omitir” muchas filas si no cumplen con todas las condiciones al unirse.

Prima

Es más legible Todas las condiciones están en un solo lugar y las filas para actualizar están en un solo lugar

Para SQLite usa la propiedad RowID para hacer la actualización:

 update Table set column = 'NewValue' where RowID = (select t1.RowID from Table t1 join Table t2 fd on t1.JoinField = t2.JoinField where t2.SelectValue = 'FooMyBarPlease');