Actualización de SQL de una tabla a otra basada en una coincidencia de ID

929

Tengo una base de datos con account numbersy card numbers. Los relaciono con un archivo con updatecualquier número de tarjeta con el número de cuenta, de modo que solo estoy trabajando con números de cuenta.

Creé una vista que vincula la tabla con la base de datos de la cuenta / tarjeta para devolver el Table IDnúmero de cuenta y el relacionado, y ahora necesito actualizar esos registros donde la ID coincide con el Número de cuenta.

Esta es la Sales_Importtabla, donde el account numbercampo necesita ser actualizado:

LeadID  AccountNumber
147         5807811235
150         5807811326
185         7006100100007267039

Y esta es la RetrieveAccountNumbertabla, donde necesito actualizar desde:

LeadID  AccountNumber
147         7006100100007266957
150         7006100100007267039

Intenté lo siguiente, pero no tuve suerte hasta ahora:

UPDATE [Sales_Lead].[dbo].[Sales_Import] 
SET    [AccountNumber] = (SELECT RetrieveAccountNumber.AccountNumber 
                          FROM   RetrieveAccountNumber 
                          WHERE  [Sales_Lead].[dbo].[Sales_Import]. LeadID = 
                                                RetrieveAccountNumber.LeadID) 

Actualiza los números de tarjeta a números de cuenta, pero los números de cuenta se reemplazan por NULL

DineshDB
fuente

Respuestas:

1369

Creo que un UPDATE FROMcon un JOINtestamento ayudará:

MS SQL

UPDATE
    Sales_Import
SET
    Sales_Import.AccountNumber = RAN.AccountNumber
FROM
    Sales_Import SI
INNER JOIN
    RetrieveAccountNumber RAN
ON 
    SI.LeadID = RAN.LeadID;

MySQL y MariaDB

UPDATE
    Sales_Import SI,
    RetrieveAccountNumber RAN
SET
    SI.AccountNumber = RAN.AccountNumber
WHERE
    SI.LeadID = RAN.LeadID;
Mark S. Rasmussen
fuente
18
Es posible que desee utilizar el alias de la tabla en la cláusula UPDATE, de lo contrario, causará problemas si se une a la tabla en cualquier momento.
Tom H
15
En la cláusula set, debe cambiar SI.AccountNumbera, de lo AccountNumbercontrario, fallará.
AaronLS
1
MS-Access usa una ACTUALIZACIÓN diferente con la Declaración JOIN. Eche un vistazo a: sql-und-xml.de/sql-tutorial/…
Christian Ammer
92
esto parece estar bien para mssql pero no parece funcionar en mysql. Esto parece hacer el trabajo sin embargo: UPDATE Sales_Import, RetrieveAccountNumber SET Sales_Import.AccountNumber = RetrieveAccountNumber.AccountNumber where Sales_Import.LeadID = RetrieveAccountNumber.LeadID;. Un poco fuera de tema pero puede ser útil
Edd
77
Creo que no hay necesidad de la unión interna. Vonki solución por debajo de las obras: UPDATE [Sales_Lead] [dbo] [Sales_Import] SET [ACCOUNTNUMBER] = RetrieveAccountNumber.AccountNumber DE DONDE RetrieveAccountNumber [Sales_Lead] [dbo] [Sales_Import] .LeadID = RetrieveAccountNumber.LeadID....
Gutti
289

La manera simple de copiar el contenido de una tabla a otra es la siguiente:

UPDATE table2 
SET table2.col1 = table1.col1, 
table2.col2 = table1.col2,
...
FROM table1, table2 
WHERE table1.memberid = table2.memberid

También puede agregar la condición para copiar los datos particulares.

Shivkant
fuente
2
Esto funciona, pero no necesita table2 en FROM UPDATE table2 SET table2.col1 = table1.col1, table2.col2 = table1.col2, ... FROM table1 WHERE table1.memberid = table2.memberid
Sirentec
2
Esto no funcionó, pero ACTUALIZA table2, table1 SET table2.col1 = table1.col1, ... WHERE table1.memberid = table2.memberid (mysql y phpmyadmin)
Tom Kuschel
156

Para SQL Server 2008 +, el uso MERGEde la UPDATE ... FROMsintaxis patentada tiene cierto atractivo.

Además de ser SQL estándar y, por lo tanto, más portátil, también generará un error en el caso de que haya varias filas unidas en el lado de origen (y, por lo tanto, múltiples valores diferentes posibles para usar en la actualización) en lugar de que el resultado final sea indeterminado .

MERGE INTO Sales_Import
   USING RetrieveAccountNumber
      ON Sales_Import.LeadID = RetrieveAccountNumber.LeadID
WHEN MATCHED THEN
   UPDATE 
      SET AccountNumber = RetrieveAccountNumber.AccountNumber;

Desafortunadamente, la elección de cuál usar puede no depender únicamente del estilo preferido. La implementación de MERGEen SQL Server se ha visto afectada por varios errores. Aaron Bertrand ha compilado una lista de los reportados aquí .

Martin Smith
fuente
11
Atención a MERGE.
Jakub Januszkiewicz
2
Nunca supe sobre la sintaxis de fusión. Es mucho más limpio que Update + Join.
Tony Ashworth
+1 para informar sobre la implementación de MERGE SQL Server
AFract
1
Los argumentos para usar MERGE (incluidos los de la publicación de sqlblog.com vinculado anteriormente) pueden ser convincentes, pero una cosa a tener en cuenta podría ser que según MSDN : ... La declaración MERGE funciona mejor cuando las dos tablas tienen una mezcla compleja de características coincidentes ... Al simplemente actualizar una tabla basada en las filas de otra tabla, se puede lograr un mejor rendimiento y escalabilidad con las instrucciones básicas INSERT, UPDATE y DELETE
Tony Pulokas
1
@ jkp1187 Esta pregunta está etiquetada como SQL Server. Entonces RE: FWIW - aproximadamente cero.
Martin Smith
104

Respuesta genérica para futuros desarrolladores.

servidor SQL

UPDATE 
     t1
SET 
     t1.column = t2.column
FROM 
     Table1 t1 
     INNER JOIN Table2 t2 
     ON t1.id = t2.id;

Oracle (y SQL Server)

UPDATE 
     t1
SET 
     t1.colmun = t2.column 
FROM 
     Table1 t1, 
     Table2 t2 
WHERE 
     t1.ID = t2.ID;

MySQL

UPDATE 
     Table1 t1, 
     Table2 t2
SET 
     t1.column = t2.column 
WHERE
     t1.ID = t2.ID;
Tigerjz32
fuente
2
Al menos para SQL Server, use el alias en lugar del nombre de la tabla en la cláusula de actualización superior (en update t1...lugar de update Table1...)
gordon el
2
La versión de Oracle no funciona. Obteniendo ORA-00933
ka3ak
35

Para PostgreSQL:

UPDATE Sales_Import SI
SET AccountNumber = RAN.AccountNumber
FROM RetrieveAccountNumber RAN
WHERE RAN.LeadID = SI.LeadID; 
petter
fuente
34

Parece que está utilizando MSSQL, entonces, si no recuerdo mal, se hace así:

UPDATE [Sales_Lead].[dbo].[Sales_Import] SET [AccountNumber] = 
RetrieveAccountNumber.AccountNumber 
FROM RetrieveAccountNumber 
WHERE [Sales_Lead].[dbo].[Sales_Import].LeadID = RetrieveAccountNumber.LeadID
Vinko Vrsalovic
fuente
33

Tuve el mismo problema con la foo.newconfiguración nullde filas fooque no tenían una clave coincidente bar. Hice algo como esto en Oracle:

actualizar foo
set foo.new = (seleccione bar.new
                  del bar 
                  donde foo.key = bar.key)
donde existe (seleccione 1
              del bar
              donde foo.key = bar.key)
Kjell Andreassen
fuente
44
¿Por qué se requiere DONDE EXISTE ?
Georg Schölly
66
Porque cada fila en foo que no tiene una coincidencia en la barra terminó siendo nula, porque la instrucción select produjo nulo. Espero que esto haya sido más claro que mi primer intento de explicarlo.
Kjell Andreassen
compruebe esta respuesta a continuación stackoverflow.com/questions/224732/…
Basheer AL-MOMANI
@KjellAndreassen Has resuelto mi problema. Gracias por tu codigo.
Bhavin Thummar
27

Para MySql que funciona bien:

UPDATE
    Sales_Import SI,RetrieveAccountNumber RAN
SET
    SI.AccountNumber = RAN.AccountNumber
WHERE
    SI.LeadID = RAN.LeadID
marsanvi
fuente
26

Esto es lo que funcionó para mí en SQL Server:

UPDATE [AspNetUsers] SET

[AspNetUsers].[OrganizationId] = [UserProfile].[OrganizationId],
[AspNetUsers].[Name] = [UserProfile].[Name]

FROM [AspNetUsers], [UserProfile]
WHERE [AspNetUsers].[Id] = [UserProfile].[Id];
Abhimanyu
fuente
18

Gracias por las respuestas Encontré una solución aunque.

UPDATE Sales_Import 
SET    AccountNumber = (SELECT RetrieveAccountNumber.AccountNumber 
                          FROM   RetrieveAccountNumber 
                          WHERE  Sales_Import.leadid =RetrieveAccountNumber.LeadID) 
WHERE Sales_Import.leadid = (SELECT  RetrieveAccountNumber.LeadID 
                             FROM   RetrieveAccountNumber 
                             WHERE  Sales_Import.leadid = RetrieveAccountNumber.LeadID)  
Martin Smith
fuente
17
Independientemente de si el código aquí funciona o no, probablemente debería mirar las otras dos soluciones publicadas. Son mucho más claros y mucho menos propensos a errores, y casi con certeza son más rápidos.
Tom H
3
Solo una nota sobre esta solución, UPDATE ... FROM es propietaria, por lo tanto, si no puede usar la declaración MERGE porque está usando SQL 2005 o anterior, este es un método compatible con ANSI para realizar actualizaciones con una fuente de tabla en MSSQL. Fuente: sqlblog.com/blogs/hugo_kornelis/archive/2008/03/10/…
pseudocoder
1
la única solución que funciona para mí porque es una declaración de actualización SQL estándar (ACTUALIZAR ESTABLECER DONDE), muchas gracias
Basheer AL-MOMANI
13

En caso de que las tablas estén en bases de datos diferentes. (MSSQL)

update database1..Ciudad
set CiudadDistrito=c2.CiudadDistrito

FROM database1..Ciudad c1
 inner join 
  database2..Ciudad c2 on c2.CiudadID=c1.CiudadID
Maurico Bello
fuente
10

Use el siguiente bloque de consulta para actualizar la Tabla1 con la Tabla2 según la ID:

UPDATE Sales_Import, RetrieveAccountNumber 
SET Sales_Import.AccountNumber = RetrieveAccountNumber.AccountNumber 
where Sales_Import.LeadID = RetrieveAccountNumber.LeadID;

Esta es la forma más fácil de abordar este problema.

Gil Baggio
fuente
8

MS Sql

UPDATE  c4 SET Price=cp.Price*p.FactorRate FROM TableNamea_A c4
inner join TableNamea_B p on c4.Calcid=p.calcid 
inner join TableNamea_A cp on c4.Calcid=cp.calcid 
WHERE c4..Name='MyName';

Oracle 11g

        MERGE INTO  TableNamea_A u 
        using
        (
                SELECT c4.TableName_A_ID,(cp.Price*p.FactorRate) as CalcTot 
                FROM TableNamea_A c4
                inner join TableNamea_B p on c4.Calcid=p.calcid 
                inner join TableNamea_A cp on c4.Calcid=cp.calcid 
                WHERE p.Name='MyName' 
        )  rt
        on (u.TableNamea_A_ID=rt.TableNamea_B_ID)
        WHEN MATCHED THEN
        Update set Price=CalcTot  ;
salman samadi
fuente
3

actualizar dentro de la misma tabla:

  DECLARE @TB1 TABLE
    (
        No Int
        ,Name NVarchar(50)
        ,linkNo int
    )

    DECLARE @TB2 TABLE
    (
        No Int
        ,Name NVarchar(50)
        ,linkNo int
    )

    INSERT INTO @TB1 VALUES(1,'changed person data',  0);
    INSERT INTO @TB1 VALUES(2,'old linked data of person', 1);

INSERT INTO @TB2 SELECT * FROM @TB1 WHERE linkNo = 0


SELECT * FROM @TB1
SELECT * FROM @TB2


    UPDATE @TB1 
        SET Name = T2.Name
    FROM        @TB1 T1
    INNER JOIN  @TB2 T2 ON T2.No = T1.linkNo

    SELECT * FROM @TB1
PNC
fuente
3

El siguiente SQL que alguien sugirió, NO funciona en SQL Server. Esta sintaxis me recuerda a mi clase de la vieja escuela:

UPDATE table2 
SET table2.col1 = table1.col1, 
table2.col2 = table1.col2,
...
FROM table1, table2 
WHERE table1.memberid = table2.memberid

Todas las demás consultas que utilizan NOT INo NOT EXISTSno se recomiendan. Se muestran NULL porque OP compara el conjunto de datos completo con un subconjunto más pequeño, por lo que, por supuesto, habrá un problema de coincidencia. Esto debe solucionarse escribiendo un SQL adecuado con el problema correcto en JOINlugar de esquivarlo mediante el uso NOT IN. Puede encontrar otros problemas al usar NOT INo NOT EXISTSen este caso.

Mi voto por el primero, que es la forma convencional de actualizar una tabla basada en otra tabla uniéndose en SQL Server. Como dije, no puede usar dos tablas en la misma UPDATEdeclaración en SQL Server a menos que las una primero.

Dr. Inner Join
fuente
2
Solo puedo decir que en SQL Server 2017 esto funciona perfectamente bien. Solo como una nota para las futuras personas que vienen. No es necesario unirse a ellos.
SharpShade
3

funciona con postgresql

UPDATE application
SET omts_received_date = (
    SELECT
        date_created
    FROM
        application_history
    WHERE
        application.id = application_history.application_id
    AND application_history.application_status_id = 8
);
jakentus
fuente
1

Pensé que este es un ejemplo simple si alguien se lo pone más fácil,

        DECLARE @TB1 TABLE
        (
            No Int
            ,Name NVarchar(50)
        )

        DECLARE @TB2 TABLE
        (
            No Int
            ,Name NVarchar(50)
        )

        INSERT INTO @TB1 VALUES(1,'asdf');
        INSERT INTO @TB1 VALUES(2,'awerq');


        INSERT INTO @TB2 VALUES(1,';oiup');
        INSERT INTO @TB2 VALUES(2,'lkjhj');

        SELECT * FROM @TB1

        UPDATE @TB1 SET Name =S.Name
        FROM @TB1 T
        INNER JOIN @TB2 S
                ON S.No = T.No

        SELECT * FROM @TB1
usuario824910
fuente
0

Oracle 11g

merge into Sales_Import
using RetrieveAccountNumber
on (Sales_Import.LeadId = RetrieveAccountNumber.LeadId)
when matched then update set Sales_Import.AccountNumber = RetrieveAccountNumber.AccountNumber;
Bruno
fuente
-1

Esto le permitirá actualizar una tabla basada en el valor de la columna que no se encuentra en otra tabla.

    UPDATE table1 SET table1.column = 'some_new_val' WHERE table1.id IN (
            SELECT * 
            FROM (
                    SELECT table1.id
                    FROM  table1 
                    LEFT JOIN table2 ON ( table2.column = table1.column ) 
                    WHERE table1.column = 'some_expected_val'
                    AND table12.column IS NULL
            ) AS Xalias
    )

Esto actualizará una tabla basada en el valor de la columna que se encuentra en ambas tablas.

    UPDATE table1 SET table1.column = 'some_new_val' WHERE table1.id IN (
            SELECT * 
            FROM (
                    SELECT table1.id
                    FROM  table1 
                    JOIN table2 ON ( table2.column = table1.column ) 
                    WHERE table1.column = 'some_expected_val'
            ) AS Xalias
    )
CG_DEV
fuente
-1

prueba esto :

UPDATE
    Table_A
SET
    Table_A.AccountNumber = Table_B.AccountNumber ,
FROM
    dbo.Sales_Import AS Table_A
    INNER JOIN dbo.RetrieveAccountNumber AS Table_B
        ON Table_A.LeadID = Table_B.LeadID 
WHERE
    Table_A.LeadID = Table_B.LeadID
Oriel.F
fuente
-2

Me gustaría agregar una cosa extra.

No actualice un valor con el mismo valor, genera un registro adicional y una sobrecarga innecesaria. Vea el ejemplo a continuación: solo realizará la actualización en 2 registros a pesar de vincular en 3.

DROP TABLE #TMP1
DROP TABLE #TMP2
CREATE TABLE #TMP1(LeadID Int,AccountNumber NVarchar(50))
CREATE TABLE #TMP2(LeadID Int,AccountNumber NVarchar(50))

INSERT INTO #TMP1 VALUES
(147,'5807811235')
,(150,'5807811326')
,(185,'7006100100007267039');

INSERT INTO #TMP2 VALUES
(147,'7006100100007266957')
,(150,'7006100100007267039')
,(185,'7006100100007267039');

UPDATE A
SET A.AccountNumber = B.AccountNumber
FROM
    #TMP1 A 
        INNER JOIN #TMP2 B
        ON
        A.LeadID = B.LeadID
WHERE
    A.AccountNumber <> B.AccountNumber  --DON'T OVERWRITE A VALUE WITH THE SAME VALUE

SELECT * FROM #TMP1
pacreely
fuente
-3

Si las respuestas anteriores no funcionan, intente esto

Update Sales_Import A left join RetrieveAccountNumber B on A.LeadID = B.LeadID
Set A.AccountNumber = B.AccountNumber
where A.LeadID = B.LeadID 
Shaw
fuente