Como posso fazer uma declaração de atualização com JOIN in SQL?

preciso de actualizar esta tabela em SQL Server 2005 com dados da sua tabela 'pai', ver abaixo:

Venda

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

Ud

id  (int)
assid  (int)

sale.assid contém o valor correcto para actualizar ud.assid.

Que consulta fará isso? Mas não sei se é possível.

Author: Ronan Boiteau, 2009-08-18

14 answers

A sintaxe depende estritamente do SQL DBMS que está a usar. Aqui estão algumas maneiras de fazê-lo em ANSI/ISO (aka deve trabalhar em qualquer SQL DBMS), MySQL, SQL Server, e Oracle. Ser informado que o meu sugeriu ANSI/ISO método geralmente será muito mais lento do que os outros dois métodos, mas se você estiver usando um SQL SGBD outros que o MySQL, SQL Server ou Oracle, então ele pode ser a única maneira de ir (por exemplo, se o SQL SGBD não suporta 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 Servidor:

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

Oráculo:

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
Author: Eric, 2018-05-13 20:14:44

Isto deve funcionar no servidor SQL:

update ud 
set assid = sale.assid
from sale
where sale.udid = id
 119
Author: 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
Author: user1154043, 2015-11-09 13:26:21

Uma abordagem SQL padrão seria

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

No servidor SQL pode usar uma junção

UPDATE ud
SET assid = s.assid
FROM ud u
JOIN sale s ON u.id=s.id
 39
Author: 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
Author: alfonx, 2014-05-08 07:52:18

Pesquisa simplificada de actualização usando JOIN - ing múltiplas tabelas.

   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 e some_column como 123456 são nomes de tabelas de demonstração, nomes de colunas e ids. Substitua-os pelos nomes válidos.

 18
Author: Vinit Kadkol, 2014-07-14 07:15:25
Outro exemplo do porquê do SQL não ser portátil. Para o MySQL seria:
update ud, sale
set ud.assid = sale.assid
where sale.udid = ud.id;

Para mais informações leia a actualização de várias tabelas: 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
Author: Yada, 2009-11-16 19:17:16
Teradata Aster oferece outra maneira interessante de alcançar o 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
 7
Author: xhudik, 2014-07-03 10:22:18
{[[2]} estava a pensar que o servidor SQL no topo do post funcionaria para o Sybase, uma vez que ambos são T-SQL, mas infelizmente não.

Para o Sybase descobri que a actualização tem de estar na própria tabela e não no nome falso:

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

A seguinte instrução com a palavra-chave é usada para actualizar várias linhas com uma junção

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

MySQL

Você terá o melhor desempenho se esquecer a cláusula onde e colocar todas as condições na expressão ON.

Eu acho que isso é porque a consulta primeiro tem que se juntar às tabelas, em seguida, executa a cláusula onde sobre isso, então se você pode reduzir o que é necessário para se juntar, então essa é a maneira rápida de obter os resultados/fazer o udpate.

Exemplo

Cenário

Tem uma tabela de utilizadores. Eles podem fazer login usando seu nome de usuário ou e-mail ou numero. Estas contas podem ser ativas (1) ou inativas (0). Este quadro tem 50000 linhas

Então você tem uma tabela de usuários para desativar de uma vez porque você descobre que todos eles fizeram algo ruim. Esta tabela, no entanto, tem uma coluna com nomes de usuário, e-mails e números de conta misturados. Ele também tem um indicador "has_run" que precisa ser definido para 1 (true) quando ele foi executado

Query

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;

Raciocínio

Se tivéssemos de nos unir apenas às condições, essencialmente precisa verificar cada linha 4 vezes para ver se ele deve se juntar, e potencialmente retornar muitas mais linhas. No entanto, ao dar-lhe mais condições ele pode "pular" um monte de linhas se eles não atender todas as condições ao aderir.

Bónus

É mais legível. Todas as condições estão num só lugar e as linhas a actualizar estão num só lugar
 2
Author: 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
Author: Abdullah Yousuf, 2016-12-19 11:40:06

E em MS ACCESS:

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

Para o SQLite use a propriedade do RowID para fazer a actualização:

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
Author: KeithTheBiped, 2018-05-13 14:45:29