Sua
UPDATE
consulta deve ficar assim:UPDATE table2 t2
SET val2 = t1.val1
FROM table1 t1
WHERE t2.table2_id = t1.table2_id
AND t2.val2 IS DISTINCT FROM t1.val1; -- optional, see below
Do jeito que você tinha, não havia ligação entre as linhas individuais das duas tabelas. Cada linha seria buscada em
table1
para cada linha em table2
. Isso não fazia sentido (de maneira cara) e também acionava o erro de sintaxe, pois uma expressão de subconsulta nesse local só pode retornar um único valor. Eu consertei isso juntando as duas tabelas em
table2_id
. Substitua isso com o que realmente liga os dois. Eu reescrevi o
UPDATE
para entrar em table1
(com o FROM
cláusula) em vez de executar subconsultas correlacionadas, porque isso geralmente é mais rápido em uma ordem de magnitude.Isso também impede que
table2.val2
seria anulado onde nenhuma linha correspondente fosse encontrada em table1
. Em vez disso, nada acontece com essas linhas com esta forma de consulta. Você pode adicionar expressões de tabela ao
FROM
list como faria em um SELECT
simples (tabelas, subconsultas, funções de retorno de conjunto, ...). O manual:from_list
Uma lista de expressões de tabela, permitindo que colunas de outras tabelas apareçam noWHERE
condição e as expressões de atualização. Isso é semelhante à lista de tabelas que podem ser especificadas noFROM
Cláusula de umSELECT
demonstração. Observe que a tabela de destino não deve aparecer nafrom_list
, a menos que você pretenda uma autojunção (nesse caso, deve aparecer com um alias nofrom_list
).
O
WHERE
final cláusula impede atualizações que não mudariam nada - o que é praticamente sempre uma boa ideia (custo quase total, mas sem ganho, exceções exóticas se aplicam). Se o valor antigo e o novo forem garantidos como NOT NULL
, simplifique para:AND t2.val2 <> t1.val1
- Como posso (ou posso) SELECT DISTINCT em várias colunas?