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

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.

preguntado el 18 de agosto de 09 a las 08:08

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ó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? -

16 Respuestas

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

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

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

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. - makciook

@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

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;

contestado el 08 de mayo de 14 a las 08:05

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

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

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

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

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

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

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

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

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

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. - KeithTheBiped

Muy útil: usar RowID lo hizo mucho más rápido que mis intentos anteriores sin él. - Mark E.

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 or haz tu propia pregunta.