我正在尝试在PostgreSQL 8.0中编写以下MySQL查询(特别是使用Redshift):
DELETE t1 FROM table t1
LEFT JOIN table t2 ON (
t1.field = t2.field AND
t1.field2 = t2.field2
)
WHERE t1.field > 0
PostgreSQL 8.0不支持DELETE FROM table USING
。 docs中的示例表示您可以在where子句中引用其他表中的列,但这不起作用,因为我正在加入同一个表中我从中删除。另一个示例是子选择查询,但我使用的表的主键有四列,因此我无法找到使其工作的方法。
答案 0 :(得分:7)
Amazon Redshift可能基于Postgres 8.0,但非常不同。
我没有使用它,但是the manual informs, that the USING
clause is supported in DELETE
statements:
只需使用现代形式:
DELETE FROM tbl
USING tbl t2
WHERE t2.field = tbl.field
AND t2.field2 = tbl.field2
AND t2.pkey <> tbl.pkey -- exclude self-join
AND tbl.field > 0;
这在MySQL语句中假定JOIN
而不是LEFT JOIN
,这没有任何意义。我还添加了条件AND t2.pkey <> t1.pkey
,以使其成为有用的查询。这排除了加入自身的行。 pkey
是主键列。
此查询的作用:
删除field
和field2
中同一个非空值的同一个表中至少存在一个其他行的所有行。删除所有此类重复项,而不会在每组中留下一行。
要保留(例如)每组重复项pkey
最小的行,请使用t2.pkey < t2.pkey
。
EXISTS
半连接(正如@wilplasser已经暗示过的)可能是更好的选择,特别是如果可以连接多行(一行只能删除一次):
DELETE FROM tbl
WHERE field > 0
AND EXISTS (
SELECT 1
FROM tbl t2
WHERE t2.field = tbl.field
AND t2.field2 = tbl.field2
AND t2.pkey <> tbl.pkey
);
答案 1 :(得分:2)
我不理解mysql语法,但你可能想要这个:
DELETE FROM mytablet1
WHERE t1.field > 0
-- don't need this self-join if {field,field2}
-- are a candidate key for mytable
-- (in that case, the exists-subquery would detect _exactly_ the
-- same tuples as the ones to be deleted, which always succeeds)
-- AND EXISTS (
-- SELECT *
-- FROM mytable t2
-- WHERE t1.field = t2.field
-- AND t1.field2 = t2.field2
-- )
;