ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# DELETE ## Name DELETE -- 删除一个表中的行 ## Synopsis ``` [ WITH [ RECURSIVE ] _with_query_ [, ...] ] DELETE FROM [ ONLY ] _table_name_ [ * ] [ [ AS ] _alias_ ] [ USING _using_list_ ] [ WHERE _condition_ | WHERE CURRENT OF _cursor_name_ ] [ RETURNING * | _output_expression_ [ [ AS ] _output_name_ ] [, ...] ] ``` ## 描述 `DELETE`从指定的表里删除满足`WHERE`子句的行。 如果`WHERE`子句不存在,将删除表中所有行。结果是一个有效的空表。 > **Tip:** [TRUNCATE](#calibre_link-89)是一个PostgreSQL扩展, 它提供一个更快的从表中删除所有行的机制。 使用数据库中其它表的信息删除某个表中的数据行有两个办法:使用子查询, 或者在`USING`子句中声明额外的表。哪种技巧更合适取决于特定的环境。 可选的`RETURNING`子句将使得`DELETE`计算并返回实际被删除了的行。 任何使用表字段的表达式和/或`USING`中提到的其他表的字段, 都可以用于计算。`RETURNING`列表的语法和`SELECT`输出列表的语法相同。 要对表进行删除,你必须对它有`DELETE`权限,同样也必须有`USING` 子句的表以及`_condition_`上读取的表的 `SELECT`权限。 ## 参数 `_with_query_` `WITH`子句允许指定一个或多个可以通过`DELETE`查询中的名字引用的子查询。 参阅[Section 7.8](#calibre_link-515)和[SELECT](#calibre_link-104)获取详细信息。 `_table_name_` 要删除行的表的名字(可以有模式修饰)。如果在表的名字前指定了`ONLY`, 则只从指定的表中删除匹配的行。如果没有指定`ONLY`,则从指定的表及其所有子表中的删除匹配的行。 可选的,可以在表名的后面指定`*`以明确的指出包括后代表。 `_alias_` 目标表的别名。如果提供了别名,那么它将完全掩盖实际的表名。例如给定`DELETE FROM foo AS f` 之后,`DELETE`语句的剩余部分必须使用`f`而不是`foo`来引用该表。 `_using_list_` 表表达式列表,允许来自其他表的列出现在`WHERE`条件中。这与可以在 `SELECT`命令的[_FROM_ 子句](#calibre_link-516) 中指定的表列表相似。例如,可以为该表的名字声明一个别名。不要在 `_using_list_`里重复目标表,除非你希望产生一个自连接。 `_condition_` 一个返回`boolean`值的表达式,只用表达式返回`true`的行被删除。 `_cursor_name_` 在`WHERE CURRENT OF`条件中使用的游标的名字。要删除的行是最近从这个游标获取到的。 该游标必须是一个在`DELETE`的目标表中非分组的查询。请注意,`WHERE CURRENT OF` 不能和一个布尔条件一起指定,参阅[DECLARE](#calibre_link-72)获取更多关于和`WHERE CURRENT OF` 一起使用游标的信息。 `_output_expression_` 计算并在删除行后由`DELETE`命令返回的一个表达式。该表达式可以使用由 `_table_name_`命名的表的任意字段名或在`USING` 中列出的表。`*`返回所有字段。 `_output_name_` 用于返回的列名称。 ## 输出 成功时,`DELETE`命令返回形如 ``` DELETE _count_ ``` 的标签。`_count_`是被删除的行数。 请注意,当删除被`BEFORE DELETE`触发器取消时,这个数字可能小于匹配 `_condition_`的行数。 如果`_count_`为 0 则没有行被该查询删除, 这个不认为是错误。 如果`DELETE`命令包含一个`RETURNING`子句,那么其结果非常类似于 `SELECT`语句基于`RETURNING`子句中包含的字段和值列表的结果, 只是基于被删除的行进行计算而已。 ## 注意 PostgreSQL允许你在`WHERE`条件里引用其它表的字段, 方法是在`USING`子句里声明其它表。比如,要删除给出制片商制作的所有电影,可以: ``` DELETE FROM films USING producers WHERE producer_id = producers.id AND producers.name = 'foo'; ``` 这里实际发生的事情是在`films`和`producers`之间的一个连接, 然后所有成功连接的`films`行都标记为删除。这个语法不是标准的,更标准的语法是这么做: ``` DELETE FROM films WHERE producer_id IN (SELECT id FROM producers WHERE name = 'foo'); ``` 有时候连接风格比子查询风格更容易写或者执行更快。 ## 例子 删除所有电影(films)但不删除音乐(musicals): ``` DELETE FROM films WHERE kind <> 'Musical'; ``` 清空`films`表: ``` DELETE FROM films; ``` 从 tasks 表及其子表中删除,并返回所有被删除的行: ``` DELETE FROM tasks WHERE status = 'DONE' RETURNING *; ``` 删除游标`c_tasks`当前指向的`tasks`的行: ``` DELETE FROM tasks WHERE CURRENT OF c_tasks; ``` ## 兼容性 这条命令遵循SQL标准,但是`USING`和`RETURNING` 子句是PostgreSQL的扩展,就像在`DELETE`中使用`WITH`。