Удаление дубликатов наборов строк - PullRequest
0 голосов
/ 25 апреля 2020

Данные

CREATE TABLE #tbl_LinkedInvoices(
    InvoiceNbr              varchar(50)
,   AssociatedInvoiceNbr    varchar(50)
,   RowNbr                  int
,   AssociatedRowNbr        int
)
INSERT INTO #tbl_LinkedInvoices(
        InvoiceNbr, AssociatedInvoiceNbr, RowNbr, AssociatedRowNbr)
VALUES 
    ('A0001', 'A1001', 1, 4),
    ('A0002', 'A2002', 2, 5),
    ('A0002', 'A3002', 3, 6),
    ('A1001', 'A0001', 4, 1),
    ('A2002', 'A0002', 5, 2),
    ('A3002', 'A0002', 6, 3)

    SELECT * FROM #tbl_LinkedInvoices

Задача / цель

tbl_LinkedInvoices предназначена для идентификации AssociatedInvoiceNbrs b, с которым InvoiceNbr a связан. Таким образом, набор может появляться в таблице несколько раз, начиная с (a, b) = (b,a). Чтобы устранить эти повторные появления, добавляются поля RowNbr и AssociatedRowNbr для получения сгруппированных последовательностей.

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

Сценарий

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

DECLARE @RowCounter int
DECLARE @RemoveRow int
SET @RowCounter = 1



IF EXISTS (SELECT 
              RowNbr
           FROM #tbl_LinkedInvoices WHERE RowNbr = (SELECT AssociatedRowNbr FROM #tbl_LinkedInvoices)
)
BEGIN
   SET @RemoveRow = (SELECT RowNbr FROM #tbl_LinkedINvoices
                     WHERE RowNbr = (
                            SELECT AssociatedRowNbr FROM #tbl_LinkedInvoices WHERE RowNbr =@RowCounter ))
    BEGIN
        DELETE FROM #tbl_LinkedInvoices
        WHERE
        RowNbr = @RemoveRow
    END
    BEGIN
        SET @RowCounter = @RowCounter + 1
    END
END

Ошибка

Msg 512, Level 16, State 1, Line 212
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

1 Ответ

1 голос
/ 25 апреля 2020

Если Я правильно следил за вами, вы можете выполнить удаление «зеркальных» записей в одном утверждении, не используя дополнительные вычисляемые столбцы:

delete t
from #tbl_LinkedInvoices t
where exists (
    select 1 
    from #tbl_LinkedInvoices t1 
    where 
        t1.AssociatedInvoiceNbr = t.InvoiceNbr
        and t1.InvoiceNbr = t.AssociatedInvoiceNbr
        and t1.AssociatedInvoiceNbr > t.AssociatedInvoiceNbr
)

При этом удаляются зеркальные записи сохраняя тот, чей InvoiceNbr меньше чем AssociatedInvoiceNbr.

Демонстрация на DB Fiddle с вашими данными выборки.

После выполнения оператора delete содержимое таблицы:

InvoiceNbr | AssociatedInvoiceNbr | RowNbr | AssociatedRowNbr
:--------- | :------------------- | -----: | ---------------:
A0001      | A1001                |      1 |                4
A0002      | A2002                |      2 |                5
A0002      | A3002                |      3 |                6
...