Sql 如何删除成对的匹配行?

Sql 如何删除成对的匹配行?,sql,database,sqlanywhere,Sql,Database,Sqlanywhere,我有一个表,其中包含销售订单数据订单号、产品号、销售价格等 然而,表格中充斥着更正和各种其他无效数据。其中一个主要问题是,通过添加一个新行来输入更正,该新行的总金额为负数,等于上一个订单的金额。销售人员并不总是很彻底,经常给出新的订单号,或者甚至没有在更正中列出产品号 我想删除所有总计为负的行,以及它们的匹配行或任何其他总计为正的行 我的第一个想法是简单地删除所有负的总计行和所有具有相反总计的正行。然而,由于许多负订单存在多个正订单,这会导致许多错误删除的正行 如何删除所有合计为负数的行,以及每

我有一个表,其中包含销售订单数据订单号、产品号、销售价格等

然而,表格中充斥着更正和各种其他无效数据。其中一个主要问题是,通过添加一个新行来输入更正,该新行的总金额为负数,等于上一个订单的金额。销售人员并不总是很彻底,经常给出新的订单号,或者甚至没有在更正中列出产品号

我想删除所有总计为负的行,以及它们的匹配行或任何其他总计为正的行

我的第一个想法是简单地删除所有负的总计行和所有具有相反总计的正行。然而,由于许多负订单存在多个正订单,这会导致许多错误删除的正行


如何删除所有合计为负数的行,以及每个合计为负数的行各删除一行?

根据数据量的不同,我只会采用暴力方式

选择临时表中的所有负总行

使用光标遍历每一行,然后在时间戳、订单号或任何主键上使用max查询数据库中的单个匹配项。删除那个匹配的行

然后删除所有负行


毫无疑问,您可以使用一个子查询并在一条语句中完成它,但当我找到并测试它时,我将使用上面的命令完成这项工作:

链接这两行的共享标识符是什么?没有这一点,您就不能这样做,因为您没有任何东西可以链接行

不管怎样,它会是这样的

DELETE MyTable
WHERE EXISTS (
    SELECT * FROM MyTable M2
    GROUP BY M2.LinkID
    HAVING SUM(M2.ValueCol) < 0 AND MyTable.KeyCol = M2.KeyCol
    )

在执行之前,我会运行一次内部SELECT,而不运行包装删除,以查看数据看起来是否正常,但我非常确定这会很好

DELETE FROM
   orders
WHERE
   orderID IN (
       SELECT
          orderID
       FROM (
          SELECT 
             MIN(orderID) orderID, total
          FROM
             orders
          WHERE
             total IN (
                SELECT
                   total * -1
                FROM
                   orders
                WHERE
                   total < 0
             )
          GROUP BY
             total
      )derived
   )

DELETE FROM
    orders
WHERE
    total < 0

无论发生什么情况,数据清理任务都是痛苦的。根据您所描述的,没有足够的信息来完全自动化此任务。这是典型的数据清理

首先,你需要和你的直属经理谈谈,让他知道问题的严重性。数据都搞糟了不是你的错,在不丢失任何有效信息和不中断销售业务的情况下修复数据需要时间

关于数据清理最重要的提示是,尝试完全自动化会带来更多麻烦。您的策略应该是通过处理简单的案例来减少问题,直到您可以手动完成剩余的工作。总是会有复杂的边缘情况,试图用聪明的SQL处理所有这些情况是一个递减回报的练习

注意低垂的果实,负修正有一个有效的订单号,因此你可以与它打算取消的订单有很强的相关性

在剩余底片和具有相同数量的最近单订单行之间创建关联。如果可以,请使用其他列将它们关联起来,例如,如果更正是由输入原始订单的同一销售人员输入的

下一步是删除订单号有效的负片,但它会映射到多行,这些行的总和等于总值

然后开始将没有顺序号的负片匹配到多行,这些行的总和等于校正中的值。这可能很难实现自动化,但此时底片的数量可能足够少,您可以通过逐个观察手动完成

另一个技巧是SQLAnywhere似乎具有多表删除语法。我在任何地方都不使用SQL,但我在在线文档中发现了这一点:

Syntax

DELETE [ row-limitation ] 
  [ FROM ] [ owner.]table-expression
  [ FROM table-list [,...] ]
  [ WHERE search-condition ]
  [ ORDER BY { expression | integer } [ ASC | DESC ], ... ]
  [ OPTION( query-hint, ... ) ]
看起来第一个FROM子句列出了要删除其中行的表。第二个FROM子句允许您进行连接以限制行。由于您可能正在进行自联接,请记住,您需要在第一个FROM中提供别名aka correlation name,以避免歧义