Din UPDATE
frågan ska se ut så här:
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
Som du hade det fanns det ingen koppling mellan enskilda rader i de två tabellerna. Varje rad skulle hämtas från table1
för varje rad i table2
. Detta var meningslöst (på ett dyrt sätt) och utlöste också syntaxfelet, eftersom ett subquery-uttryck på den här platsen bara tillåts returnera ett enda värde.
Jag fixade detta genom att sammanfoga de två tabellerna på table2_id
. Ersätt det med det som faktiskt länkar de två.
Jag skrev om UPDATE
för att gå med i table1
(med FROM
klausul) istället för att köra korrelerade underfrågor, eftersom det vanligtvis är snabbare med en storleksordning.
Det förhindrar också att table2.val2
skulle annulleras där ingen matchande rad hittas i table1
. Istället inget händer med sådana rader med denna form av frågan.
Du kan lägga till tabelluttryck till FROM
lista som i en vanlig SELECT
(tabeller, underfrågor, set-returnerande funktioner, ...). Manualen:
from_list
En lista med tabelluttryck som tillåter kolumner från andra tabeller att visas i
WHERE
skick och uppdateringsuttrycken. Detta liknar listan över tabeller som kan specificeras iFROM
Klausul i enSELECT
påstående. Observera att måltabellen inte får visas ifrom_list
, såvida du inte avser att gå med själv (i så fall måste den visas med ett alias ifrom_list
).
Den sista WHERE
klausul förhindrar uppdateringar som inte skulle förändra någonting - vilket praktiskt taget alltid är en bra idé (nästan full kostnad men ingen vinst, exotiska undantag gäller). Om både gamla och nya värden garanteras vara NOT NULL
, förenkla till:
AND t2.val2 <> t1.val1
- Hur väljer jag (eller kan jag) DISTINCT på flera kolumner?