从表A中删除加入Redshift中的表A.

时间:2014-04-30 16:18:46

标签: sql amazon-redshift delete-row

我正在尝试在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 USINGdocs中的示例表示您可以在where子句中引用其他表中的列,但这不起作用,因为我正在加入同一个表中我从中删除。另一个示例是子选择查询,但我使用的表的主键有四列,因此我无法找到使其工作的方法。

2 个答案:

答案 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是主键列。

此查询的作用:
删除fieldfield2中同一个非空值的同一个表中至少存在一个其他行的所有行。删除所有此类重复项,而不会在每组中留下一行。

要保留(例如)每组重复项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
--    )
    ;