CodeGym /课程 /SQL SELF /UPDATE 更新数据

UPDATE 更新数据

SQL SELF
第 21 级 , 课程 2
可用

今天我们要搞定你新知识库里另一个重要的砖头——数据更新。来看看在PostgreSQL里怎么用 UPDATE 命令改已有的信息。为啥这很重要?因为现实生活里的数据不是一成不变的。比如你朋友换了手机号,或者学生换了班——你肯定想把这些信息在数据库里也改一下。

比如你高中暗恋的Svetka Sokolova突然变成了Svetka Khachaturyan(生活嘛,就是这样),这就得在你的数据库里改一下。需要更新数据的场景其实挺多的:

  • 修正记录里的错误。
  • 更新信息(搬家、状态变了啥的)。
  • 批量改数据,比如给员工涨工资。

数据更新就是在不加新记录的情况下,把表里一行或多行的某些列的值改掉。

UPDATE 命令的语法

PostgreSQL里的 UPDATE 命令语法其实挺直观的。来看下结构:

UPDATE 表名
SET 列1 = 值1,
    列2 = 值2
WHERE 条件;

解释一下:

  • 表名:你要改的表的名字。
  • SET 列 = 值:指定要改哪个列,改成啥值。
  • WHERE 条件:条件,指定哪些行要被更新(这个超重要,不然全表都改了)。

关键点:如果你忘了加 WHERE(或者写错了),你改的会是表里的所有行。后果很严重。

例子:改学生的名字

假设我们有个 students 表,里面有 idnameemail 这几列。我们想把 id = 1 的学生名字改成 "Maria Chi"。

UPDATE students
SET name = 'Maria Chi'
WHERE id = 1;

这条命令会找到 id = 1 的那行,把 name 列改成新值。很简单吧?

更新多列

有时候你得一次改一条记录里的好几个值。比如学生不仅改了名字,还换了邮箱。这样写:

UPDATE students
SET name = 'Otto Lin',
    email = 'otto.lin@example.com'
WHERE id = 2;

这里我们同时更新了 nameemail,针对 id = 2 的学生。PostgreSQL支持在 SET 里用逗号分隔写多个 列=值

更新多行

如果你要一次改多行数据怎么办?比如你想把一组学生转到新班级。可以根据某个条件批量更新。假设有个 group_number 字段,我们要把所有 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 字段来更新 students 里的 debt。每条 students 记录通过 student_idpayments 关联。

语法像这样:

UPDATE students
SET debt = payments.due_amount
FROM payments
WHERE students.id = payments.student_id;

发生了什么:

  • PostgreSQL 用 FROM payments 作为数据来源。
  • 通过 WHERE 条件把两表的行关联起来。
  • 只更新那些在 payments 里有对应记录的 students 行。

注意: 这个 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 old_debt, 
    payments.due_amount AS new_debt
FROM students
    JOIN payments ON students.id = payments.student_id;

结果会显示:

  • 原来的欠款值(old_debt);
  • 新值,就是 payments 表里的 new_debt

这样可以先验证下逻辑对不对,再决定要不要真的覆盖数据。

可能遇到的坑

  • 如果 payments一个学生有多条记录UPDATE 会报错:more than one row returned。要么用聚合函数(MAXSUMLIMIT 1),要么保证 payments 里的 student_id 是唯一的。
  • 别忘了,UPDATE ... FROM 是PostgreSQL的特性,别的数据库(比如MySQL)可能不支持。

实用例子

例子1:改学生状态

比如学生完成了课程就变成“毕业生”。我们有个 status 列。要把 completed_course = true 的学生状态都改成“毕业生”:

UPDATE students
SET status = '毕业生'
WHERE completed_course = true;

例子2:给员工涨工资

如果你有个 employees 表,想给销售部的所有人涨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。想象下:你有1万员工的数据库,一不小心给所有人都涨了工资。虽然员工们会很开心,但你老板可能就不高兴了。

另一个常见错误——更新错了列。每次都要再三确认你到底在写什么、写到哪。先用 SELECT 查查再 UPDATE,能帮你省下不少麻烦。

2
任务
SQL SELF, 第 21 级, 课程 2
已锁定
有条件地更新员工工资
有条件地更新员工工资
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION