【问题标题】:Removing Duplicate Sets of Rows删除重复的行集
【发布时间】:2020-08-08 14:13:29
【问题描述】:

数据

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 bInvoiceNbr a。因此,从(a, b) = (b,a) 起,一个集合可以在表中出现多次。为了解决这些重复出现的问题,添加了 RowNbrAssociatedRowNbr 字段以提供分组序列。

使用已识别的重复行,删除重复行,在表中保留一条唯一记录。当前脚本产生错误,期待可能有更好的方法来编写查询。

脚本

使用计数器检查重复行是否仍然存在,如果确实删除该行,直到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.

【问题讨论】:

  • 错误不是很清楚吗?使用in 而不是=
  • @GordonLinoff - IN 返回全部或不返回,因为值存在于两列中。

标签: sql sql-server tsql duplicates sql-delete


【解决方案1】:

如果我正确地跟着你,你可以在单个语句中执行“镜像”记录的删除,而无需使用额外的计算列:

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 的记录。

Demo on DB Fiddle 与您的示例数据。

delete语句执行后,表的内容为:

发票Nbr | AssociatedInvoiceNbr |行号 |关联行号 :--------- | :-------------------- | -----: | ---------------: A0001 | A1001 | 1 | 4 A0002 | A2002 | 2 | 5 A0002 | A3002 | 3 | 6

【讨论】:

  • 这最终奏效了。巧妙地使用EXISTS 并利用最后一个比较运算符在重复的情况下在数学上给出优先级。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-07
  • 1970-01-01
  • 2012-12-07
相关资源
最近更新 更多