¿Cómo puedo hacer una instrucción UPDATE con JOIN en SQL Server?
Frecuentes
Visto 1,652 equipos
1394
Necesito actualizar esta tabla en SQL Server con datos de su tabla 'principal', consulte a continuación:
Mesa: venta
id (int)
udid (int)
assid (int)
Tabla: ud
id (int)
assid (int)
sale.assid
contiene el valor correcto para actualizar ud.assid
.
¿Qué consulta hará esto? Estoy pensando en un join
pero no estoy seguro de si es posible.
16 Respuestas
2516
La sintaxis depende estrictamente del DBMS SQL que esté utilizando. Aquí hay algunas formas de hacerlo en ANSI / ISO (también conocido como debería funcionar en cualquier DBMS SQL), MySQL, SQL Server y Oracle. Tenga en cuenta que mi método ANSI / ISO sugerido generalmente será mucho más lento que los otros dos métodos, pero si está utilizando un DBMS SQL que no sea MySQL, SQL Server u Oracle, entonces puede ser el único camino a seguir (p. Ej. si su DBMS SQL no es compatible 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
PostgresSQL:
update ud
set assid = s.assid
from sale s
where ud.id = s.udid;
Tenga en cuenta que la tabla de objetivos no debe repetirse en el FROM
cláusula para Postgres.
Oracle:
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
);
respondido 10 mar '20, 03:03
Me parece que MySQL set assid = s.assid
debiera ser set u.assid = s.assid
. - dotancohen
En la sintaxis ANSI, ¿qué sucede si SELECT después del =
devuelve más de una fila? - Desechar cuenta
@ ThrowawayAccount3Million Probablemente fallaría. AFAIK, este tipo de operación esperaría un valor escalar y arrojará un error si se le da un conjunto de resultados en su lugar. - señor francisco
¡Deseo que el OP elija mejores nombres para su tabla y columnas! no es tan legible / intuitivo ... - S. Serpooshan
Postgre 9.3 funcionó solo usando update ud set assid = s.assid
- apilar debajo
148
Esto debería funcionar en SQL Server:
update ud
set assid = sale.assid
from sale
where sale.udid = id
Respondido 31 ago 17, 20:08
101
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
respondido 09 nov., 15:13
La respuesta sería más útil si usara los nombres de tabla / columna utilizados en la pregunta. ¿Por qué hay 3 tablas en tu respuesta? - alfonso
51
Un enfoque estándar de SQL sería
UPDATE ud
SET assid = (SELECT assid FROM sale s WHERE ud.id=s.id)
En SQL Server puede usar una combinación
UPDATE ud
SET assid = s.assid
FROM ud u
JOIN sale s ON u.id=s.id
Respondido 18 ago 09, 13:08
Con el primero, no puede coincidir en más de 2 columnas, pero unirse funciona muy bien. - makciok
@makciook: ¿eh? Puede agregar más condiciones en el WHERE
cláusula si desea hacer coincidir en columnas adicionales. - sirir
Solo una pizca ... pero creo que el OP significaba sale.udid = ud.id. Y no sale.id. - Skippy Von Drake
39
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;
contestado el 08 de mayo de 14 a las 08:05
26
Consulta de actualización simplificada usando SUSCRÍBETE-ing múltiples 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 identificadores. Reemplácelos con los nombres válidos.
Respondido 14 Jul 14, 08:07
Sintaxis no válida para MS SQL. - Materias de la fuente
16
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]
respondido 16 nov., 09:19
¡Haz +1 en el comentario "por qué SQL no es realmente portátil"! La portabilidad es tan frágil que simplemente declarar una variable romperá la portabilidad entre muchos de los motores de bases de datos populares. - jeff moden
10
Teradata Aster ofrece otra forma interesante de cómo lograr el objetivo:
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
Respondido 03 Jul 14, 11:07
8
Estaba pensando que el de SQL-Server 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 en la tabla en sí, no en el alias:
update ud
set u.assid = s.assid
from ud u
inner join sale s on
u.id = s.udid
respondido 19 nov., 14:08
8
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, por lo que si puede reducir lo que se requiere para unirse, esa es la forma más rápida de obtener los resultados / hacer la actualización.
Ejemplo
Guión
Tienes una tabla de usuarios. Pueden iniciar sesión con su nombre de usuario, correo electrónico o número de cuenta. Estas cuentas pueden estar activas (1) o inactivas (0). Esta tabla tiene 50000 filas
Luego tiene una tabla de usuarios para deshabilitar de una 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 debe 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 en las condiciones OR, esencialmente necesitaríamos verificar cada fila 4 veces para ver si debería unirse 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.
Bono
Es más legible. Todas las condiciones están en un solo lugar y las filas para actualizar están en un solo lugar
Respondido 09 Feb 18, 16:02
7
La siguiente declaración 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
Respondido 06 Abr '16, 12:04
5
La forma más sencilla es utilizar la expresión de tabla común (CTE) introducido en SQL 2005
with cte as
(select u.assid col1 ,s.assid col2 from ud u inner join sale s on u.id = s.udid)
update cte set col1=col2
Respondido 23 Abr '19, 18:04
4
Y en MS ACCESS:
UPDATE ud
INNER JOIN sale ON ud.id = sale.udid
SET ud.assid = sale.assid;
respondido 07 mar '17, 18:03
Como precaución, el SET debe venir inmediatamente después de la definición del juego de registros. Acabo de intentar resolver un escenario similar en una base de datos de Access, que necesitaba una cláusula WHERE (no la aceptaría como una condición ON válida). DONDE tenía que llegar el último para evitar errores de sintaxis. - dodecafono
3
UPDATE tblAppraisalBasicData
SET tblAppraisalBasicData.ISCbo=1
FROM tblAppraisalBasicData SI INNER JOIN aaa_test RAN ON SI.EmpID = RAN.ID
Respondido el 19 de diciembre de 16 a las 11:12
3
Para SQLite, use la propiedad RowID para realizar la actualización:
update Table set column = 'NewValue'
where RowID =
(select t1.RowID from Table t1
join Table2 t2 on t1.JoinField = t2.JoinField
where t2.SelectValue = 'FooMyBarPlease');
Respondido 13 Oct 18, 17:10
¿Podrías explicar esto un poco? - Mohamed Noureldin
@MohammedNoureldin Trataré de explicarlo. El problema es cómo actualizar una tabla con el resultado de una consulta en una combinación usando la misma tabla. La instrucción (sub-selección) actúa como una combinación y devuelve un campo del sistema, RowID, que es un número único para cada fila de una tabla. Dado que la sub-selección puede devolver varias filas, "donde RowID =" selecciona una única fila correcta de la sub-selección resultante y actualiza la columna. Avísame si necesitas más aclaraciones o necesitas encontrar una variación sobre este tema. - Keithelbípedo
Muy útil: usar RowID lo hizo mucho más rápido que mis intentos anteriores sin él. - Mark E.
3
Prueba este, creo que te funcionará
update ud
set ud.assid = sale.assid
from ud
Inner join sale on ud.id = sale.udid
where sale.udid is not null
respondido 23 nov., 18:15
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas sql sql-server tsql sql-server-2005 sql-update or haz tu propia pregunta.
algunas relaciones entre las tablas? ¿Cómo se puede saber qué registro de la venta corresponde a qué registro de la ud? ¿Se basa en la identificación como clave principal en ambas tablas? - Cătălin Pitiș
¿Cómo se puede actualizar UD? Solo tiene el asistente y su propia identificación. ¿Podría dar un ejemplo en términos de valores reales que existen y los registros que le gustaría cambiar o agregar como resultado del script? - Bernhard Hofmann
Véase también SO pregunta ... stackoverflow.com/questions/982919/sql-update-query-using-joins - SteveC
Alias de usuario en una consulta como stackoverflow.com/questions/982919/sql-update-query-using-joins - Imran Muhammad