Skip to content

PostgreSQL - DELETE

PostgreSQL 的 DELETE 语句用于从表中删除现有行。务必使用 WHERE 子句来指定要删除的行。如果您省略 WHERE 子句,表中的所有行都将被删除!

DELETE FROM table_name
[ WHERE condition ];

安全提示:在运行 DELETE 语句之前,最佳实践是首先运行一个带有相同 WHERE 子句的 SELECT 语句,以验证您正在删除正确的行。例如:SELECT * FROM table_name WHERE condition;

让我们设置一个 products 表来操作。

CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
status VARCHAR(20) DEFAULT 'active',
price NUMERIC(10, 2)
);
INSERT INTO products (name, status, price) VALUES
('Laptop', 'active', 1200.00),
('Mouse', 'active', 25.00),
('Keyboard', 'discontinued', 75.00),
('Monitor', 'active', 300.00),
('Old Webcam', 'discontinued', 15.00);

现在,让我们删除 id 为 2 的单个产品。

testdb=# DELETE FROM products WHERE id = 2;
DELETE 1

“DELETE 1”消息表示成功删除了 1 行。现在让我们删除所有状态为 ‘discontinued’(已停产)的产品。

testdb=# DELETE FROM products WHERE status = 'discontinued';
DELETE 2

表中现在只包含活动产品:

testdb=# SELECT * FROM products ORDER BY id;
id | name | status | price
----+---------+--------+---------
1 | Laptop | active | 1200.00
4 | Monitor | active | 300.00
(2 rows)

PostgreSQL 中一个强大的功能是 RETURNING 子句,它允许 DELETE 语句返回刚刚删除的行的值。这对于日志记录、审计或在不运行单独 SELECT 查询的情况下准确了解删除了哪些内容非常有用。

DELETE FROM table_name
WHERE condition
RETURNING column1, column2, ... | *;

让我们删除 ‘Monitor’ 产品,并在同一命令中查看其 id 和 name 的返回值。

testdb=# DELETE FROM products WHERE name = 'Monitor' RETURNING id, name;
id | name
----+---------
4 | Monitor
(1 row)

如果您的目标是从表中删除所有行,您有两种选择:DELETE FROM table_name; 或 TRUNCATE table_name;。它们达到类似的结果,但有重要的区别。

方面DELETETRUNCATE
性能较慢。逐行扫描并删除。快得多。解除分配表的整个数据页。
触发器为每一行触发 ON DELETE 触发器。不触发 ON DELETE 触发器。
事务日志记录每一行删除操作。极少的日志记录,使其更快。
序列/标识列不会重置序列。默认情况下(使用 RESTART IDENTITY),会将序列重置为其起始值。
WHERE 子句允许。不允许。它总是删除所有行。

要快速清空 products 表并重置其 id 序列:

testdb=# TRUNCATE TABLE products RESTART IDENTITY;
TRUNCATE TABLE

在开发或数据加载过程中需要快速清空大表时,选择 TRUNCATE。当您需要选择性地删除行,或者您有必须触发的 DELETE 触发器时,使用 DELETE。