Как я могу удалить пары совпадающих строк? - PullRequest
0 голосов
/ 12 ноября 2009

У меня есть таблица, в которой содержатся данные заказа на продажу (номер заказа, номер продукта, цена продажи и т. Д.).

Однако таблица заполнена исправлениями и другими неверными данными. Одна из основных проблем заключается в том, что поправки были введены путем добавления новой строки с отрицательным итогом, равным сумме предыдущего заказа. Продавцы не всегда были внимательны и часто давали новый номер заказа или даже не указывали номер продукта в исправлении.

Я хотел бы удалить все строки с отрицательным итогом вместе с их соответствием (или любым другим с таким же итогом) положительным итогом строки.

Моей первой мыслью было просто удалить все отрицательные итоговые строки и все положительные строки, которые имеют противоположное общее количество. Однако, поскольку для многих отрицательных порядков существует несколько положительных порядков, это приводит к множеству ошибочно удаленных положительных строк.

Как я могу удалить все строки с отрицательным итогом вместе с одной строкой для каждой, которая имеет обратный итог?

Ответы [ 4 ]

1 голос
/ 12 ноября 2009

Задачи очистки данных являются болезненными, несмотря ни на что. Из того, что вы описали, недостаточно информации для полной автоматизации этой задачи. Это типично для очистки данных.

Сначала вам нужно поговорить с вашим непосредственным руководителем и сообщить ему масштаб проблемы. Вы не виноваты, что все данные испорчены, и потребуется время, чтобы исправить их, не теряя никакой достоверной информации и не прерывая операции продаж.

Самый важный совет по очистке данных состоит в том, что больше проблем, чем стоит пытаться полностью автоматизировать . Ваша стратегия должна состоять в том, чтобы уменьшить проблему, заботясь о простых случаях, пока вы не можете сделать остальное вручную. Всегда будут сложные крайние случаи, и попытка обработать их все с помощью умного SQL - упражнение для уменьшения отдачи.

  1. Позаботьтесь о низко висящих фруктах, где отрицательная «коррекция» имеет действительный номер заказа, чтобы вы могли сделать сильную корреляцию с заказом, который он намерен отменить.

  2. Создание корреляции между оставшимися отрицательными значениями и самыми последними строками одного заказа с одинаковым количеством. Если возможно, используйте другие столбцы, чтобы сопоставить их, например, если исправление введено тем же продавцом, который ввел исходный заказ.

  3. Следующим этапом будет удаление негативов, если номер заказа действителен, но он сопоставляется с несколькими строками, которые суммируют до общего значения.

  4. Затем начните сопоставлять негативы без порядковых номеров с несколькими строками, которые суммируют до значения в коррекции. Это может быть сложно автоматизировать, но к этому времени число негативов может быть достаточно мало, чтобы вы могли сделать это вручную, посмотрев на них один за другим.

Другой совет заключается в том, что SQL Anywhere имеет синтаксис DELETE для нескольких таблиц. Я нигде не использую 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, чтобы избежать двусмысленности.

1 голос
/ 12 ноября 2009

в зависимости от количества данных, я бы просто сделал это методом грубой силы.

выделить все отрицательные итоговые строки во временную таблицу

используйте курсор, чтобы пройти через каждую строку, затем запросите в базе данных одно совпадение (возможно, используя max () для отметки времени, номера заказа или любого первичного ключа, который у вас может быть. Удалите эту одну «совпадающую» строку.

затем удалите все отрицательные строки

Нет сомнений, что вы можете использовать подзапрос и сделать это в одном утверждении, но к тому времени, как я разберусь с ним и проверим его, я справлюсь с работой, описанной выше:)

0 голосов
/ 12 ноября 2009

Я бы запустил внутренний 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
0 голосов
/ 12 ноября 2009

Что такое общий идентификатор, который связывает 2 строки? Без этого вы не сможете, потому что вам не с чем связать строки

Во всяком случае, это было бы что-то вроде

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