根据select语句删除重复行

时间:2014-08-26 19:44:18

标签: sql sql-server-2008

我有两个select语句返回重复数据。我想要完成的是删除重复的一条腿。但是我很难以编程方式进入第二行。

select i.InvID, i.UID, i.StartDate, i.EndDate, i.Minutes,i.ABID from inv_v i, InvoiceLines_v i2 where 
i.Period = '2014/08'
and i.EndDate = i2.EndDate
and i.Minutes = i2.Minutes
and i.Uid <> i2.Uid
and i.abid = i2.abid
order by i.EndDate

此select语句返回以下数据。

enter image description here

正如您所看到的,它会返回minutes相同的重复行ABID相同但InvID不同。我需要做的是删除标准匹配的InvID之一。无论哪一个。

第二个select语句返回不同的数据。

select i.InvID,  i.UID, i.StartDate, i.EndDate, i.Minutes from InvoiceLines_v i, InvoiceLines_v i2 where 
i.Period = '2014/08'
and i.EndDate = i2.EndDate
and i.Uid = i2.Uid
and i.Abid <> i2.Abid 
and i.Language <> i2.Language
order by i.startdate desc

enter image description here

在这个select语句中,我想删除InvID,其中UID相同,然后选择最低的Mintues。在这种情况下,我会删除以下InvID:25376762537210

我的目标是删除这些行......

我可以使用cursor抓取InvID并通过简单的删除语句删除它来完成此操作,但我正试图远离游标。

关于如何实现这一目标的任何建议?

4 个答案:

答案 0 :(得分:1)

我遇到了有关重复数据的类似问题,有些人告诉我使用分区和其他方法,但这些都会导致性能问题 但是,我在表格中有一个主键,通过它我可以从重复数据中选择一行然后将其删除。

例如在第一个选择语句&#34;分钟&#34;和&#34; ABID&#34;是考虑数据重复的标准。但是&#34; Invid&#34;可用于区分重复的行。

因此,您可以使用以下查询来删除重复项。

  delete from inv_i where inv_id in (select max(inv_id) from inv_i group by minutes,abid having count(*) > 1 );

这个简单的概念对我很有帮助。如果&#34; Inv_id&#34;它会对您的情况有所帮助。是独一无二的。

答案 1 :(得分:1)

您可以使用exists删除除InvID以外的所有重复项以外的所有重复项,方法是删除存在另一行且值相同且InvID

delete from inv_v 
where exists (
    select 1 from inv_v i2
    where i2.InvID > inv_v.InvID
    and i2.minutes = inv_v.minutes
    and i2.EndDate = inv_v.EndDate
    and i2.abid = inv_v.abid
    and i2.uid <> inv_v.uid -- not sure why <> is used here, copied from question
)

答案 2 :(得分:0)

;WITH CTE AS
 (
 SELECT InvID
      ,[UID]
      ,StartDate
      ,EndDate
      ,[Minutes] 
      ,ROW_NUMBER() OVER (PARTITION BY InvID, [UID] ORDER BY [Minutes] ASC) rn 
 FROM InvoiceLines_v  
 )
SELECT *
FROM CTE 
WHERE rn = 1

答案 3 :(得分:0)

将ORIGINAL_TABLE替换为您的表名。

QUERY 1:

  WITH DUP_TABLE AS
             (
              SELECT ROW_NUMBER()
              OVER (PARTITION BY minutes, ABID ORDER BY minutes, ABID) As ROW_NO
              FROM <ORIGINAL_TABLE>
             )
 DELETE FROM DUP_TABLE WHERE ROW_NO > 1;

QUERY 2:

  WITH DUP_TABLE AS
             (
              SELECT ROW_NUMBER()
              OVER (PARTITION BY UID ORDER BY minutes) As ROW_NO
              FROM <ORIGINAL_TABLE>
             )
 DELETE FROM DUP_TABLE WHERE ROW_NO > 1;