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
.
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
);
Isto deve funcionar no servidor SQL:
update ud
set assid = sale.assid
from sale
where sale.udid = id
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
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
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;
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.
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]
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
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
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
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ó lugarUPDATE tblAppraisalBasicData
SET tblAppraisalBasicData.ISCbo=1
FROM tblAppraisalBasicData SI INNER JOIN aaa_test RAN ON SI.EmpID = RAN.ID
E em MS ACCESS:
UPDATE ud
INNER JOIN sale ON ud.id = sale.udid
SET ud.assid = sale.assid;
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');