Comment puis-je faire une instruction UPDATE avec JOIN in SQL?

J'ai besoin de mettre à jour cette table dans SQL Server 2005 avec les données de sa table 'parent', voir ci-dessous:

Vente

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

Ud

id  (int)
assid  (int)

sale.assid contient la valeur correcte à mettre à jour ud.assid.

Quelle requête va faire cela? Je pense à un join mais je ne suis pas sûr que ce soit possible.

1070
demandé sur Ronan Boiteau 2009-08-18 15:40:07

14 réponses

La syntaxe dépend strictement du SGBD SQL que vous utilisez. Voici quelques façons de le faire en ANSI/ISO (aka devrait fonctionner sur N'importe quel SGBD SQL), MySQL, SQL Server et Oracle. Sachez que ma méthode ANSI/ISO suggérée sera généralement beaucoup plus lente que les deux autres méthodes, mais si vous utilisez un SGBD SQL autre que MySQL, SQL Server ou Oracle, cela peut être la seule solution (par exemple si votre SGBD SQL ne prend pas en charge 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

SQL Serveur:

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

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
 );
1990
répondu Eric 2018-05-13 20:14:44

Cela devrait fonctionner dans SQL Server:

update ud 
set assid = sale.assid
from sale
where sale.udid = id
119
répondu edosoft 2017-08-31 19:32:50

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 
84
répondu user1154043 2015-11-09 13:26:21

Une approche SQL standard serait

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

Sur SQL Server, vous pouvez utiliser une jointure

UPDATE ud
SET assid = s.assid
FROM ud u
JOIN sale s ON u.id=s.id
39
répondu MattH 2009-08-18 12:34:52

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;
28
répondu alfonx 2014-05-08 07:52:18

Requête de mise à jour simplifiée à l'aide deJOIN -ing plusieurs tables.

   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

Note - first_table, second_table, third_table et some_column comme 123456 sont des noms de table de démonstration, des noms de colonnes et des identifiants. Les remplacer par les noms valides.

18
répondu Vinit Kadkol 2014-07-14 07:15:25

Un autre exemple pourquoi SQL n'est pas vraiment portable.

Pour MySQL ce serait:

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

Pour plus d'informations, lisez multiple table update: 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]
11
répondu Yada 2009-11-16 19:17:16

Teradata Aster offre une autre façon intéressante d'atteindre l'objectif:

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
7
répondu xhudik 2014-07-03 10:22:18

Je pensais que le serveur SQL dans le post supérieur fonctionnerait pour Sybase car ils sont tous deux T-SQL mais malheureusement pas.

Pour Sybase j'ai trouvé que la mise à jour doit être sur la table elle-même pas l'alias:

update ud
set u.assid = s.assid
from ud u
    inner join sale s on
        u.id = s.udid
6
répondu Ken Goh 2014-11-19 08:24:18

L'instruction suivante avec le mot-clé FROM est utilisée pour mettre à jour plusieurs lignes avec une jointure

UPDATE users 
set users.DivisionId=divisions.DivisionId
from divisions join users on divisions.Name=users.Division
4
répondu Sheryar Nizar 2016-04-06 11:34:28

MySQL

Vous obtiendrez les meilleures performances si vous oubliez la clause where et placez toutes les conditions dans L'expression ON.

Je pense que c'est parce que d'abord la requête doit joindre les tables, puis exécute la clause where sur, donc si vous pouvez réduire ce qui est nécessaire pour rejoindre le jeun façon à obtenir les résultats/faire le udpate.

Exemple

Scénario

Vous avez une table d'utilisateurs. Ils peuvent se connecter en utilisant leur nom d'utilisateur ou e-mail ou account_number. Ces comptes peuvent être actifs (1) ou inactifs (0). Cette table a 50000 lignes

Vous avez alors une table d'utilisateurs à désactiver d'un seul coup parce que vous découvrez qu'ils ont tous fait quelque chose de mal. Cependant, cette table a une colonne avec des noms d'Utilisateur, des e-mails et des numéros de Compte mélangés. Il a également un indicateur" has_run " qui doit être défini sur 1 (true) quand il a été exécuté

Requête

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;

Raisonnement

Si nous devions nous joindre uniquement aux conditions ou, il faudrait essentiellement vérifiez chaque ligne 4 fois pour voir si elle devrait se joindre, et potentiellement retourner beaucoup plus de lignes. Cependant, en lui donnant plus de conditions, il peut "sauter" beaucoup de lignes si elles ne remplissent pas toutes les conditions lors de l'adhésion.

Bonus

C'est plus lisible. Toutes les conditions sont en un seul endroit et les lignes à mettre à jour sont dans un endroit

2
répondu Luke Watts 2018-02-09 16:57:54
UPDATE tblAppraisalBasicData
SET tblAppraisalBasicData.ISCbo=1
FROM tblAppraisalBasicData SI INNER JOIN  aaa_test RAN ON SI.EmpID = RAN.ID
1
répondu Abdullah Yousuf 2016-12-19 11:40:06

Et dans MS ACCESS:

UPDATE ud 
INNER JOIN sale ON ud.id = sale.udid
SET ud.assid = sale.assid;
1
répondu Richard 2017-03-07 18:38:28

Pour SQLite, utilisez la propriété RowID pour effectuer la mise à jour:

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');
0
répondu KeithTheBiped 2018-05-13 14:45:29