【问题标题】:Delete from table A joining on table A in Redshift从表 A 中删除在 Redshift 中加入表 A
【发布时间】:2014-06-17 01:51:31
【问题描述】:

我正在尝试在 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 子句中引用其他表中的列,但这在这里不起作用,因为我正在加入我要从中删除的同一张表上。另一个示例是子选择查询,但我正在使用的表的主键有四列,所以我也看不到让它工作的方法。

【问题讨论】:

  • 您看到了什么错误/结果。我看到您的查询似乎有问题的第一件事是它应该是“DELETE FROM”(删除“t1”)
  • 是的,这是一个 mysql 查询,我不希望它只在 postgresql 中工作。我根本无法在 Postgresql 8.0 中找到等价物。删除的语法非常简单。
  • 顺便说一句:table 是什么?关键字?
  • 您确定 MySQL 查询正在执行您想要的操作吗? LEFT JOIN 似乎完全没用。
  • 您应该描述查询的确切目的。损坏的 MySQL 查询并没有解决问题。

标签: sql amazon-redshift delete-row


【解决方案1】:

我不懂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
--    )
    ;

注意:出于测试目的,您可以将DELETE 关键字替换为SELECT * 或SELECT COUNT(*),并查看查询会影响哪些行。

【讨论】:

  • 我认为这正是我所需要的。让我确认一下!
【解决方案2】:

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 &lt;&gt; t1.pkey,使其成为一个有用的查询。这不包括加入自身的行。 pkey 是主键列。

此查询的作用:
删除同一表中至少存在一个 other 行且field 和field2 中具有相同非空值的所有行.所有此类重复项都将被删除,而不会在每组中留下一行。

要保留(例如)每组重复项中具有最小pkey 的行,请使用t2.pkey &lt; t2.pkey。

EXISTS 半联接(正如@wiplasser 已经暗示的那样)可能是更好的选择,尤其是在可以联接多行的情况下(无论如何,一行只能删除一次):

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 
   );

【讨论】:

  • 这让我们很接近,但它只有在 t1 和 t2 不同时才有效。就我而言,它们是相同的。抱歉,如果我不清楚,但我打算将 table 用作表名,将 t1/t2 用作别名。感谢您指出语法不同,我猜是一样的!
  • 搞笑:AND t2.pkey &lt;&gt; t1.pkey 条件仍然会删除所有满足的元组(除非不存在重复项)也许你的意思是AND t2.pkey &lt; t1.pkey ??
  • @wildplasser:嗯,是的。这就是查询的目的,因为我猜测它缺乏定义。我添加了几行来澄清。
  • 我们都可能是对的。 (或错误)OP 的意图仍然完全不清楚,至少对我来说是这样。
  • 在redshift中你不能给目标表起别名,即你必须编码DELETE FROM tbl1 USING ...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
  • 2023-03-30
  • 1970-01-01
相关资源
最近更新 更多