Ce face UPDATE ... FROM
În timp ce alte sisteme SQL folosesc sintaxa UPDATE t1 JOIN t2 ..., PostgreSQL utilizează clauza UPDATE tabel_tinta SET ... FROM tabel_sursa WHERE ... pentru a actualiza rânduri pe baza datelor din alte tabele, vederi sau liste VALUES.
Tabelul țintă este specificat imediat după UPDATE, iar tabelele suplimentare se enumeră în FROM, legătura dintre ele realizându-se în clauza WHERE.
Clauze, operatori și argumente
| Clauză / Operator | Descriere |
|---|---|
UPDATE tabel_tinta [AS t] |
Tabelul ale cărui rânduri vor fi modificate (aliasul ajută la dezambiguizarea coloanelor). |
SET col = expresie |
Atribuie noile valori; în expresie pot fi folosite și coloane din tabelele specificate în FROM. |
FROM sursa1 [, sursa2 ...] |
Aduce în context unul sau mai multe tabele, subinterogări sau liste (VALUES ...). |
WHERE t.cheie = s.cheie |
Condiția de joncțiune și filtrare; fără ea, fiecare rând din țintă s-ar potrivi cu toate rândurile din sursă. |
RETURNING ... |
Returnează rândurile actualizate (cu noile valori din tabelul țintă, dar poate include și coloane din FROM). |
Exemple
Exemplul 1: Actualizarea prețurilor dintr-un tabel temporar de import cu UPDATE … FROM
Aplicăm noile prețuri din tabelul import_preturi în tabelul produse și afișăm atât prețul nou, cât și diferența.
UPDATE produse p
SET pret = imp.pret_nou,
actualizat_la = NOW()
FROM import_preturi imp
WHERE p.sku = imp.sku
AND p.pret <> imp.pret_nou
RETURNING p.sku, p.denumire, p.pret AS pret_actualizat;
Rezultat interogare
sku | denumire | pret_actualizat
-------------+------------------------+-----------------
MON-27-4K | Monitor IPS 27 inch 4K | 1599.00
KBD-MECH-RO | Tastatură Mecanică RO | 399.00
(2 rows)
UPDATE 2
Exemplul 2: Actualizare în masă cu valori diferite per ID folosind FROM (VALUES …)
Schimbăm ordinea de afișare pentru 3 categorii distincte într-o singură interogare rapidă.
UPDATE categorii c
SET ordine_afisare = v.ordine_noua
FROM (VALUES
(10, 1),
(15, 2),
(12, 3)
) AS v(id, ordine_noua)
WHERE c.id = v.id
RETURNING c.id, c.nume, c.ordine_afisare;
Rezultat interogare
id | nume | ordine_afisare
----+------------+----------------
10 | Laptopuri | 1
15 | Monitoare | 2
12 | Periferice | 3
(3 rows)
UPDATE 3
Greșeli frecvente
- Repetarea tabelului țintă în clauza
FROM(ex:UPDATE produse p SET ... FROM produse p JOIN ...): în PostgreSQL aceasta creează un self-join neintenționat; tabelul țintă trebuie pus doar dupăUPDATE. - Dacă un rând din tabelul țintă se potrivește cu mai multe rânduri din tabelul
FROM, rezultatul este nedeterminist (doar unul dintre rândurile sursă va fi folosit pentru actualizare).
Comenzi și funcții înrudite
ON CONFLICT DO UPDATE (UPSERT): Rezolvă atomic conflictele de cheie unică la inserare: ignoră rândul duplicat sau îl actualizează pe loc.DELETE ... USING și TRUNCATE: Șterge rânduri filtrate prin joncțiuni cu DELETE … USING sau golește instantaneu tabele întregi cu TRUNCATE.INSERT INTO ... RETURNING: Inserează unul sau mai multe rânduri și returnează imediat valorile generate (ID-uri, timestamp-uri) fără o interogare suplimentară.