CodeGym /课程 /SQL SELF /DELETE 删除数据

DELETE 删除数据

SQL SELF
第 21 级 , 课程 3
可用

删除可不是随便点个按钮那么简单,这其实是一门艺术!你得删得刚刚好,别多删一条(不小心删掉的数据,晚上做梦都能吓醒你)。今天我们就来学学怎么优雅又靠谱地删数据!

删除数据,就是把表里不再符合业务逻辑或者系统需求的某些行给移除掉。比如,你要删掉已经毕业的学生,或者那些,嗯,严重违反校规的同学。又或者,你想清理一下表,只留下最新的数据。

删除操作一般用在这些场景:

  • 删掉那些已经不活跃的用户数据。
  • 清理表里的临时记录。
  • 去除重复的数据。
  • 根据业务逻辑删掉过时的记录。

DELETE 命令的语法

我们用 DELETE 命令来删数据。基本语法长这样:

DELETE FROM 表名
WHERE 条件;

主要部分:

  • DELETE FROM —— 关键字,告诉 SQL 要从哪个表里删行。
  • 表名 —— 你要删数据的表的名字。
  • WHERE 条件 —— 用来筛选要删哪些行的条件。你可以用各种比较运算符、逻辑运算符(ANDORNOT),甚至还能用子查询。

举个例子:假设我们有个 students 表,要删掉 id = 5 的学生:

DELETE FROM students
WHERE id = 5;

这个语句会把 students 表里 id(学生编号)等于 5 的那一行删掉。

注意: 如果你忘了写 WHERE 条件,PostgreSQL 会把表里的所有行都删掉。这种失误在生产环境里简直灾难级别,千万小心!

删除表里的所有行

如果你想把表里的所有行都删掉,可以直接写不带 WHERE 的语句,比如:

DELETE FROM students;

这个语句会把 所有记录 都从 students 表里删掉。但表的结构还在,只是内容变空了。

替代方案:TRUNCATE

要删掉表里的所有行,还可以用 TRUNCATE 命令。它比 DELETE 快,因为不会一行一行地写日志。比如:

TRUNCATE TABLE students;

DELETETRUNCATE 的区别:

  • DELETE 会把每一行的删除都写进事务日志,所以可以回滚。
  • TRUNCATE 不支持 WHERE 条件,也不会一条条记录日志,所以更快,但没那么灵活。

如果你只是想清空表,TRUNCATE 很棒。但如果你只想删部分数据,或者想要能回滚,还是用 DELETE 更合适。

按复杂条件删除数据

DELETE 的条件不仅可以很简单,还能很复杂,比如用逻辑运算符(ANDORNOT)或者子查询。来看例子。

例子1:删除多条记录 删掉所有年龄大于30岁且最近3个月没来上课的学生:

DELETE FROM students
WHERE age > 30 AND last_attendance_date < (CURRENT_DATE - INTERVAL '3 months');

这个语句只会删掉同时满足这两个条件的学生。

例子2:用子查询删除

假设有个 failed_students 表,里面存着因学业不及格被开除的学生 id。我们要把这些学生从 students 主表里删掉:

DELETE FROM students
WHERE id IN (SELECT student_id FROM failed_students);

这里子查询会返回 failed_students 表里的所有学生 id,DELETE 会把 students 表里对应的行删掉。

小建议

在你删数据之前,先写个 SELECT,查查你想删的内容。确认没问题后,把 SELECT 换成 DELETE,这样删掉的就是你刚查到的那些行。

实战例子

假如 id = 7 的学生要转学了,我们要把他的信息从表里删掉:

DELETE FROM students
WHERE id = 7;

执行完后查查表,确认这条记录真的被删了:

SELECT * FROM students WHERE id = 7;

如果查不到 id = 7 的记录,说明删除成功。

警告和常见错误

忘记写 WHERE 条件

DELETE 时最常见的坑就是忘了写 WHERE 条件。这样会把表里所有行都删掉,后果很严重。一定要在执行前检查你的语句!

比如这种粗心导致的事故:

DELETE FROM students;
-- 错误!所有学生都被删了。

为了避免这种事,建议你在执行 DELETE 前,先用 SELECT 测试一下 WHERE 条件。比如:

SELECT * FROM students WHERE id = 5;

如果查出来的结果没问题,再放心地用 DELETE

删除有关联的数据

如果表里有外键(FOREIGN KEY),删数据时可能会报错。比如,学生在 enrollments 表里有选课记录,PostgreSQL 就不让你直接把他从 students 表里删掉。

解决办法有:

  1. 建外键时加上 ON DELETE CASCADE,让删除自动级联。
  2. 先手动删掉关联表里的记录,再删主表里的。

手动删除关联数据的例子:

-- 先从 enrollments 表里删掉学生 5 的记录
DELETE FROM enrollments
WHERE student_id = 5;

-- 再删掉学生 5 本人
DELETE FROM students
WHERE id = 5;

用事务删除

做重要的删除操作时,建议用事务,这样出错可以回滚。

事务删除的例子:

BEGIN;

DELETE FROM students
WHERE id = 42;

-- 检查结果
SELECT * FROM students WHERE id = 42;

-- 没问题就提交
COMMIT;

-- 有问题就回滚
-- ROLLBACK;

事务的更多内容我们后面讲座再聊 :P

评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION