You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何同时从父表和子表中删除数据

问题解答

背景信息

现有两张PostgreSQL数据表,定义如下:

CREATE TABLE IF NOT EXISTS "public"."parent" (
  parent_id UUID not null,
  name TEXT not null,
)
CREATE TABLE IF NOT EXISTS "public"."child" (
  child_id UUID not null,
  parent_id UUID not null,
  name TEXT not null,
  CONSTRAINT "child_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."parent"("parent_id")
)

尝试执行以下DELETE语句时触发语法错误:

DELETE FROM parent WHERE parent_id IN (DELETE FROM child WHERE name LIKE '%whatever' RETURNING parent_id)

已知单独执行DELETE FROM child WHERE name LIKE '%whatever' RETURNING parent_id是可行的,需要解释为何外层嵌套的写法不可行。


解答

能否执行?

不能,该写法不符合SQL语法规范,会直接触发语法错误。

不可行的原因

SQL标准以及PostgreSQL的语法规则中,IN子查询的内部必须是仅返回数据的SELECT查询,而DELETE属于数据修改语句(DML)——哪怕它带RETURNING子句能返回结果集,本质上还是执行数据变更的操作,不属于IN子查询允许的输入类型。

简单来说,IN的括号里只能放SELECT语句,不能放INSERT/UPDATE/DELETE这类会修改数据的语句,哪怕它们能返回结果也不行。

正确实现方式

如果要实现“删除指定child记录后,删除对应的parent记录”的需求,推荐使用CTE(WITH子句)来完成:

WITH deleted_child_parents AS (
  DELETE FROM child 
  WHERE name LIKE '%whatever' 
  RETURNING parent_id
)
DELETE FROM parent
WHERE parent_id IN (SELECT parent_id FROM deleted_child_parents);

这种写法通过CTE先执行child的删除操作并返回parent_id,再用这个结果集作为条件删除对应的parent记录,既符合语法规范,又能保证操作的原子性。


内容的提问来源于stack exchange,提问作者hatch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 23:00:01