Espero que a instrução SQL atualize uma quantidade limitada de linhas, em vez de todas as linhas:
UPDATE Join_Test_1
SET ANumber = 3
FROM Join_Test_1 AS ST1
INNER JOIN Join_Test_2 AS ST2 ON ST1.PKID = ST2.PKID;
Espero que a declaração se comporte da mesma forma que as declarações:
UPDATE Join_Test_1
SET ANumber = 3
FROM Join_Test_2
WHERE Join_Test_1.PKID = Join_Test_2.PKID;
UPDATE Join_Test_1
SET ANumber = 3
WHERE EXISTS (SELECT * FROM Join_Test_2
WHERE Join_Test_2.PKID = Join_Test_1.PKID);
UPDATE Join_Test_1
SET ANumber = 3
WHERE PKID IN (SELECT PKID FROM Join_Test_2);
As instruções que usam a WHERE
cláusula atualizam apenas a ANumber
coluna onde PKID
há correspondências.
A instrução que usa INNER JOIN
atualiza todas as linhas da tabela.
Por que o INNER JOIN
não limita o número de linhas atualizadas?
A declaração com o pode INNER JOIN
ser reescrita para usar o JOIN
para limitar o número de linhas atualizadas?
/* Expansive Example */
CREATE TABLE Join_Test_1 (PKID SERIAL, ANumber INTEGER);
CREATE TABLE Join_Test_2 (PKID SERIAL, ANumber INTEGER);
INSERT INTO Join_Test_1 (ANumber) VALUES (1), (1);
INSERT INTO Join_Test_2 (ANumber) VALUES (2);
UPDATE Join_Test_1
SET ANumber = 3
FROM Join_Test_1 AS ST1
INNER JOIN Join_Test_2 AS ST2 ON ST1.PKID = ST2.PKID; -- Updates 2
SELECT *
FROM Join_Test_1
ORDER BY PKID;
-- 1, 3
-- 2, 3
UPDATE Join_Test_1
SET ANumber = 1; -- Update 2
UPDATE Join_Test_1
SET ANumber = 3
FROM Join_Test_2
WHERE Join_Test_1.PKID = Join_Test_2.PKID;
SELECT *
FROM Join_Test_1
ORDER BY PKID;
-- 1, 1
-- 2, 3
UPDATE Join_Test_1 SET ANumber = 1; -- Update 2
UPDATE Join_Test_1
SET ANumber = 3
WHERE PKID IN (SELECT PKID FROM Join_Test_2);
SELECT *
FROM Join_Test_1
ORDER BY PKID;
-- 1, 1
-- 2, 3
DROP TABLE IF EXISTS Join_Test_1;
DROP TABLE IF EXISTS Join_Test_2;
Existe
plpgSQL
uma maneira de atualizar uma única tabela durante a junção da seguinte maneira:Processo-01: db<>fiddle - Atualização durante a junção
Processo-02: db<>fiddle - Atualização durante a junção
Processo-03: db<>fiddle - Maneira normal
Provavelmente, ao lidar com atualizações que envolvem junções e/ou condições múltiplas ou complexas, a maneira mais legível e sustentável de fazer isso é usando a
MERGE INTO
sintaxe.Resultado:
violino
Apenas certifique-se de que sua consulta USING busque linhas exclusivas para serem correspondidas...
Você alias a tabela
Join_Test_1
, mas não chama o alias na atualização. Isso significa que aFROM
declaração é ignorada. Sua declaração é a mesma queUPDATE Join_Test_1 SET ANumber = 3
.Sua
UPDATE
declaração está simplesmente errada. Nenhuma conexão é estabelecida entre a tabela de destinoJoin_Test_1
e a segunda instânciaJoin_Test_1 AS ST1
. Você não precisa dessa segunda instância da tabela de destino no Postgres para começar - exceto para o caso raro de emular umLEFT JOIN
. Veja:Isso funcionaria:
Eu também simplifiquei e acabei com a grafia inútil de CaMeL-case. Veja:
Mas esta ainda é uma declaração duvidosa . Tudo se resume à mera existência de uma linha correspondente em
join_test_2
. Com a junção, você corre o risco de várias correspondências, o que produz resultados arbitrários. Não aparece no exemplo simplista com uma atribuição constante (teste inútil!), mas deve ser evitado em qualquer caso. Não atualize a mesma linha várias vezes.A consulta correta para o propósito é sua
EXISTS
variante, que pode ser simplificada para: