今天我們要來學一個你 SQL 基礎裡很重要的磚塊——資料更新。來看看在 PostgreSQL 裡怎麼用 UPDATE 指令改現有的資訊。為什麼這很重要?因為現實生活裡資料都不是死的啊。想像一下,你朋友換了電話號碼,或學生換到別的班級——你當然會想把這些資料在資料庫裡更新一下。
當你國高中暗戀的 Svetka Sokolova 突然變成 Svetka Khachaturyan(人生嘛,總會有這種事),這就需要你在資料庫裡改一下。需要更新資料的情境超多:
- 修正紀錄裡的錯誤。
- 更新資訊(搬家、狀態變更)。
- 大量修改資料,比如給員工加薪。
更新資料就是改變一個或多個欄位的值,針對一行或多行,不會新增新紀錄。
UPDATE 指令語法
PostgreSQL 的 UPDATE 指令語法很直觀。來看一下結構:
UPDATE 表格
SET 欄位1 = 值1,
欄位2 = 值2
WHERE 條件;
說明:
表格:你要改的那個表的名字。SET 欄位 = 值:這裡指定要改哪個欄位、改成什麼值。WHERE 條件:這個條件決定哪些行要被更新(超重要,不然會全改了)。
重點:如果你忘了加 WHERE(或寫錯),你會把整個表的所有行都改掉。這下就慘了。
範例:改學生名字
假設我們有個 students 表,欄位有 id、name、email。我們想把 id = 1 的學生名字改成 "Maria Chi"。
UPDATE students
SET name = 'Maria Chi'
WHERE id = 1;
這個指令會找到 id = 1 的那行,把 name 欄位改成新值。超簡單吧?
同時更新多個欄位
有時候你會想一次改一行裡的好幾個值。比如學生不只換名字,還換了 email。這樣做:
UPDATE students
SET name = 'Otto Lin',
email = 'otto.lin@example.com'
WHERE id = 2;
這裡我們同時更新 name 跟 email,針對 id = 2 的學生。PostgreSQL 允許你在 SET 裡用逗號分隔多組 欄位=值。
同時更新多行
如果你要一次改多行資料怎麼辦?比如你想把一群學生換到新班級。這時可以根據條件更新多行。假設有個 group_number 欄位,我們要把所有 101 班的學生換到 202 班:
UPDATE students
SET group_number = 202
WHERE group_number = 101;
這個指令會把 group_number 是 101 的所有行都改成 202。
5. WHERE 條件:小心使用!
前面說過,WHERE 就像你的救生圈。沒有它,指令會改掉整個表的所有行。比如下面這個指令會把所有學生的班級都改掉,不只 101 班。這你絕對不想發生:
UPDATE students
SET group_number = 202;
拜託,除非你真的要全改,不然一定要加 WHERE。多小心一點沒壞處。
把 UPDATE 想成一個會改表格欄位的指令,不是改行。它的目標是把某個欄位的所有格子都設成某個值。只有加了 WHERE,才會只改特定行。
根據另一個表的資料來更新
有時候我們不只是「手動填值」,而是用表 B 的資料來更新表 A。這種情境很常見——尤其是資料分開存的時候:比如計算結果在一個表,使用者資料在另一個表。
假設我們有 students 表,要用 payments 表裡的 due_amount 來更新 debt 欄位。每個 students 的紀錄都對應 payments 裡 student_id。
語法會像這樣:
UPDATE students
SET debt = payments.due_amount
FROM payments
WHERE students.id = payments.student_id;
這裡發生了什麼:
- PostgreSQL 用
FROM payments當資料來源。 - 用
WHERE條件把兩個表的行連起來。 - 只會更新
students裡有對應payments的行。
重點: 這個 UPDATE ... FROM 其實背後就是個JOIN,只是沒寫 JOIN 關鍵字。
其實底層就是 JOIN。實際上會像這樣:
UPDATE students
SET debt = p.due_amount
FROM payments p
JOIN students s ON s.id = p.student_id
WHERE students.id = p.student_id;
怎麼看會更新哪些資料
在執行 UPDATE 前,超級建議你先看一下到底會改哪些東西。可以用同樣邏輯寫個 SELECT:
SELECT
students.id,
students.name,
students.debt AS 舊_debt,
payments.due_amount AS 新_debt
FROM students
JOIN payments ON students.id = payments.student_id;
結果會顯示:
- 舊的債務值(
舊_debt); - 從
payments表來的新值(新_debt)。
這種做法可以先檢查邏輯對不對,再決定要不要真的覆蓋資料。
潛在陷阱
- 如果
payments裡一個學生有多筆紀錄,UPDATE會報錯:more than one row returned。你要嘛用聚合(MAX、SUM、LIMIT 1),要嘛確保payments裡student_id是唯一的。 - 別忘了
UPDATE ... FROM是 PostgreSQL 的特殊語法,其他資料庫(像 MySQL)不一定支援。
實用範例
範例 1:改學生狀態
假設學生完成課程後要拿到「畢業生」狀態。我們有個 status 欄位。要把 completed_course = true 的學生狀態改掉:
UPDATE students
SET status = '畢業生'
WHERE completed_course = true;
範例 2:給員工加薪
如果你有個 employees 表,要給所有在 Sales 部門的人加薪 10%:
UPDATE employees
SET salary = salary * 1.10
WHERE department = 'Sales';
這裡我們直接在 SET 裡做數學運算。這對大量更新很方便。
範例 3:條件式更新
有時候你要根據條件來更新資料。比如薪水小於 50,000 的員工加薪 20%,大於的加 10%:
UPDATE employees
SET salary = CASE
WHEN salary < 50000 THEN salary * 1.20
ELSE salary * 1.10
END;
這個指令用 CASE 結構,根據 salary 值決定怎麼加薪。
用 UPDATE 常見錯誤
你大概已經猜到最常見的錯誤是什麼了吧?沒錯,就是漏掉 WHERE。想像一下,你有一個 10,000 員工的資料庫,結果你不小心給大家都加薪了。雖然員工會很開心,但你可能就要被老闆 fire 了…
另一個常見錯誤是改錯欄位。一定要再三確認你改的是對的東西。執行 UPDATE 前先來個 SELECT,可以幫你省下超多麻煩。
GO TO FULL VERSION