如何删除成对的匹配行?

时间:2009-11-12 19:05:03

标签: sql database sqlanywhere

我有一张表格,其中包含销售订单数据(订单号,产品编号,销售价格等)。

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

我想删除所有行总数为负的行,以及匹配(或其他总数相同)的总行数。

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

如何删除总数为负的所有行,以及每个具有反向总数的一行行?

4 个答案:

答案 0 :(得分:1)

取决于有多少数据,我只是以蛮力的方式来做。

将所有负总行选择到临时表

使用游标遍历每一行,然后查询数据库以进行单个匹配(在时间戳,订单号或您可能拥有的任何主键上使用可能的max()。删除那一行“匹配”行。< / p>

然后删除所有负行

毫无疑问,您可以使用子查询并在一个语句中执行此操作,但是当我想出并测试它时,我将使用上述方法完成工作:)

答案 1 :(得分:1)

无论如何,数据清理任务都很痛苦。根据您的描述,没有足够的信息来完全自动执行此任务。这通常用于数据清理。

首先,您需要与您的直属经理进行交谈,并让他知道问题的严重程度。数据全部搞砸了,这不是你的错,而且在不丢失任何有效信息且不中断销售操作的情况下修复它需要时间。

关于数据清理的最重要提示是,比尝试完全自动化更值得麻烦。您的策略应该是通过处理简单的案例来减少问题,直到您可以手动完成其余操作。总会有复杂的边缘情况,尝试使用聪明的SQL来处理它们是一种收益递减的练习。

  1. 处理低调的果实,其中负面“修正”具有有效的订单编号,因此您可以与要取消的订单强烈关联。

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

  3. 下一阶段是删除订单号有效的负片,但它会映射到多个总和达到总值的行。

  4. 然后开始将没有订单号的负数与多个行相匹配,这些行总计到更正中的值。这可能很难实现自动化,但到目前为止,负面的数量可能足够少,您可以手动完成,通过一个接一个地观察它们。

  5. 另一个提示是SQL Anywhere似乎具有多表DELETE语法。我不使用SQL Anywhere,但我在在线文档中发现了这一点:

    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中提供别名(也称为相关名称)以避免歧义。

答案 2 :(得分:0)

链接2行的共享标识符是什么?没有这个,你就不能,因为你没有任何东西可以链接行

无论如何,它会像

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

答案 3 :(得分:0)

我执行内部SELECT,没有包装DELETE一次,在执行之前看到数据看起来没问题,但我很确定这很好

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