web-dev-qa-db-fra.com

Mise à jour SQL d'une table à une autre en fonction d'une correspondance d'ID

J'ai une base de données avec account numbers et card numbers. Je les associe à un fichier pour update tout numéro de carte associé au numéro de compte, de sorte que je ne travaille qu'avec des numéros de compte. 

J'ai créé une vue liant la table à la base de données de comptes/cartes pour renvoyer le Table ID et le numéro de compte associé. Maintenant, je dois mettre à jour les enregistrements dont l'ID correspond au numéro de compte.

Ceci est la table Sales_Import, où le champ account number doit être mis à jour:

LeadID  AccountNumber
147         5807811235
150         5807811326
185         7006100100007267039

Et voici la table RetrieveAccountNumber, où je dois mettre à jour:

LeadID  AccountNumber
147         7006100100007266957
150         7006100100007267039

J'ai essayé le ci-dessous, mais pas de chance jusqu'à présent:

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

Il met à jour les numéros de carte en numéros de compte, mais les numéros de compte sont remplacés par NULL

803
Boerseun

Je crois qu'un UPDATE FROM avec un JOIN aidera:

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 et MariaDB

UPDATE
    Sales_Import SI,
    RetrieveAccountNumber RAN
SET
    SI.AccountNumber = RAN.AccountNumber
WHERE
    SI.LeadID = RAN.LeadID;
1204
Mark S. Rasmussen

La manière simple de copier le contenu d'un tableau à un autre est la suivante:

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

Vous pouvez également ajouter la condition pour obtenir les données particulières copiées.

269
Shivkant

Pour SQL Server 2008 +, l'utilisation de MERGE plutôt que de la syntaxe propriétaire UPDATE ... FROM présente un certain attrait. 

En plus d'être SQL standard et donc plus portable, il générera également une erreur s'il existe plusieurs lignes jointes du côté source (et donc plusieurs valeurs différentes possibles à utiliser dans la mise à jour) au lieu que le résultat final soit indéterminé .

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

Malheureusement, le choix de l’utilisation ne dépend pas forcément du style préféré. L'implémentation de MERGE dans SQL Server a été affectée par divers bogues. Aaron Bertrand a compilé une liste de ceux rapportés ici .

150
Martin Smith

Réponse générique pour les futurs développeurs. 

Serveur SQL

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

Oracle (et 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;
60
Tigerjz32

On dirait que vous utilisez MSSQL, alors, si je me souviens bien, cela se fait comme suit:

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

J'ai eu le même problème avec foo.new étant défini sur null pour les lignes de foo qui n'avaient pas de clé correspondante dans bar. J'ai fait quelque chose comme ça dans Oracle:

 update foo 
 set foo.new = (sélectionnez bar.new 
 de bar 
 où foo.key = bar.key) 
 où existe (sélectionnez 1 
 de bar 
 où foo.key = bar.key) 
29
Kjell Andreassen

Pour PostgreSQL:

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

Pour MySQL, cela fonctionne bien:

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

Merci pour les réponses. J'ai trouvé une solution tho.

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)  
14
Boerseun

Voici ce qui a fonctionné pour moi dans SQL Server:

UPDATE [AspNetUsers] SET

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

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

Utilisez le bloc de requête suivant pour mettre à jour Table1 avec Table2 en fonction de l'ID:

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

C’est le moyen le plus simple pour résoudre ce problème.

3
Gil Baggio

Le SQL ci-dessous suggéré par quelqu'un, ne fonctionne pas dans SQL Server. Cette syntaxe me rappelle mon ancienne classe d'école:

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

Toutes les autres requêtes utilisant NOT IN ou NOT EXISTS ne sont pas recommandées. Les valeurs NULL apparaissent car OP compare un ensemble de données complet avec un sous-ensemble plus petit. Il y aura bien sûr un problème de correspondance. Ceci doit être corrigé en écrivant le code SQL correct avec JOIN correct au lieu d'éviter le problème en utilisant NOT IN. Vous pourriez rencontrer d'autres problèmes en utilisant NOT IN ou NOT EXISTS dans ce cas.

Mon vote pour le premier, qui est un moyen conventionnel de mettre à jour une table basée sur une autre table en rejoignant SQL Server. Comme je l'ai dit, vous ne pouvez pas utiliser deux tables dans la même instruction UPDATE dans SQL Server à moins de les joindre auparavant.

3
Dr Inner Join

mettre à jour dans la même table:

  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
3
NCP

cela fonctionne avec 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
);
2
jakentus

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  ;
1
saman samadi

Je pensais que ceci est un exemple simple, quelqu'un pourrait-il l'obtenir plus facilement, 

        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
1
user824910

Dans le cas où les tables sont dans une base de données différente. (Serveur SQL)

update database1..Ciudad
set CiudadDistrito=c2.CiudadDistrito

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

Oracle 11g

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