postgresql 基于WHERE语句的子查询的大规模删除,波斯特格雷斯

9rygscc1  于 2023-06-22  发布在  PostgreSQL
关注(0)|答案(2)|浏览(104)

我需要用IN语句做一个子查询。这样(简化):

DELETE
FROM table_1 
WHERE id_table_1 IN (SELECT string_agg(fk_id_table_1::TEXT,',') FROM table_2

我需要做了一个大规模的删除,第二子查询的基础上。问题是如果我使用IN语句,我必须使用string_agg来放置以逗号分隔的id,但id是整数,string_agg需要更改为文本,如果我将id_table_1::text IN(... subquery...)它返回空。我也尝试使用ANY,并将id放入一个整数数组中。但它显示“错误:操作员不存在:integer = integer[]"。我也试着使用EXISTS。
有人给予我点光吗?多谢了。

kgsdhlau

kgsdhlau1#

您不需要在子查询中使用string_agg函数(实际上,这将返回所有聚合id的单个值!因此与表1 ID中任何一个都不匹配)。
IN运算符的语法为:value IN (value1, value2,...),其中的值列表可以是一个 * 文字值列表 *,例如数字、字符串...或者select语句(子查询)的 * 结果为WHERE value IN (SELECT col FROM table_name)
因此,您可以将查询修复为如下所示:

DELETE
FROM table_1 
WHERE id_table_1 IN (SELECT fk_id_table_1 FROM table_2)

使用exists操作符:

DELETE
FROM table_1 T1
WHERE EXISTS (SELECT 1 FROM table_2 T2 WHERE T2.fk_id_table_1 = T1.id_table_1)
44u64gxh

44u64gxh2#

虽然你可以使用逗号分隔的列表为IN编写文字值,例如WHERE id_table_1 IN (1,2,3),但你不能以你使用的方式使用string_agg。相反,使用返回单个列的查询来创建值列表,如下所示:

DELETE
FROM table_1 
WHERE id_table_1 IN (SELECT fk_id_table_1 FROM table_2)

最好使用postgres的join delete syntax

DELETE FROM table_1
USING table_2
WHERE table_1.id_table_1 = table_2.fk_id_table_1

如果要以编程方式将查询构建为字符串,则可以使用string_agg(),但这里不是这种情况。

相关问题