0

我有一个包含销售订单数据(订单号、产品号、销售价格等)的表格。

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

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

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

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

4

4 回答 4

1

根据有多少数据,我会以蛮力的方式进行。

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

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

然后删除所有负行

毫无疑问,您可以使用子查询并在一个语句中执行它,但是当我弄清楚并测试它时,我会使用上面的方法完成工作:)

于 2009-11-12T19:11:26.880 回答
1

无论如何,数据清理任务都是痛苦的。根据您的描述,没有足够的信息来完全自动化此任务。这对于数据清理来说是典型的。

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

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

  1. 小心低垂的果实,负“修正”有一个有效的订单号,这样你就可以与它打算取消的订单建立很强的相关性。

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

  3. 下一阶段将删除订单号有效的负数,但它映射到总计为总值的多行。

  4. 然后开始将没有订单号的否定匹配到多行,这些行总和为更正中的值。这可能很难实现自动化,但此时底片的数量可能足够少,您可以通过逐一观察它们来手动完成。

另一个提示是 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以避免歧义。

于 2009-11-12T19:29:19.133 回答
0

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

无论如何,它会像

DELETE MyTable
WHERE EXISTS (
    SELECT * FROM MyTable M2
    GROUP BY M2.LinkID
    HAVING SUM(M2.ValueCol) < 0 AND MyTable.KeyCol = M2.KeyCol
    )
于 2009-11-12T19:11:36.660 回答
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
于 2009-11-12T19:20:47.173 回答