2014-10-20 103 views
0

我正在使用SQL Server。在SQL Server中刪除重複項並保留一個條件

我有以下設計的表:

ID bigint 
Number varchar(50) 
Processed int 

我有很多重複的數列

我要刪除所有重複的數字,並保持數where processed=1

舉例如果我有

Number --- Processed 
111 --- 0 
111 --- 0 
111 --- 1 

I要刪除所有,並保持最後一個

任何幫助,將不勝感激

+0

你會有任何行只有一次的數字,它沒有處理?或者你可以簡單地刪除處理過的所有內容= 0? – Tanner 2014-10-20 10:15:16

+0

@坦納我可能有重複處理= 0。我想保留所有重複中的至少一個,但是如果他們有一個處理= 1,那麼優先級將是該行的。 – HelpASisterOut 2014-10-20 10:18:43

回答

1

如果你只是想刪除其中數等於111行和處理不等於1,你可以這樣做:

delete from <table> 
where 
Number = 111 and 
Processed <> 1 

假設ID是連續的,你想保留的最後一排的每個號碼,你可以這樣做:

delete from <table> t 
left join (
    select 
     MAX(ID) filter_ID 
    from <table> 
    group by 
     Number 
) filter on 
    t.ID = filter.filter_ID 
where 
    filter.filter_ID is null 

讓每個號碼優先至少一行到加工= 1

delete from <table> t 
left join (
    select 
    ID 
    from (
     select 
      ROW_NUMBER() OVER (
       PARTITION BY 
        Number 
       ORDER BY 
        Processed DESC, 
        ID DESC 
      ) last_R, 
      ID 
     from <table> 
    ) filter 
    where 
     last_R = 1 
) filter on 
    t.ID = filter.filter_ID 
where 
    filter.filter_ID is null 
+0

有超過500,000個重複的號碼。我可能有所有處理= 0的重複項。我想保留所有重複中的至少一個,但是如果其中一個與處理= 1,則優先級將用於該行。 – HelpASisterOut 2014-10-20 10:19:22

+0

如果您想要處理的第一個條目= 1 – mxix 2014-10-20 10:24:12

0

這是我會怎麼處理這個問題:

DECLARE @NUM VARCHAR(50) 
DECLARE @TAB TABLE 
(
    NUMBER VARCHAR(50) 
) 

INSERT INTO @TAB 
SELECT number, from <table> where processed = 0 GROUP BY number HAVING COUNT(number) > 1 

DECLARE @IDToKEEP TABLE 
(
    id INT 
) 

WHILE (SELECT COUNT(*) FROM @TAB) > 0 
BEGIN 
    SELECT TOP 1 @NUM = number FROM @TAB 

    INSERT INTO @IDToKEEP 
    SELECT TOP 1 id FROM <table> WHERE number = @NUM 

    DELETE FROM @TAB WHERE number = @NUM 
END 

DELETE FROM <table> WHERE processed = 0 AND number IN (SELECT number FROM @TAB) AND id NOT IN (SELECT id FROM @IDToKEEP) 
+0

您可以將ID訂單轉換爲ASC,其中所有處理的數據都可能重複= 0。我想保留所有重複中的至少一個,但是如果其中一個與處理= 1,則優先級將用於該行。 – HelpASisterOut 2014-10-20 10:22:06

2

這裏有一個方法:

with todelete as (
     select t.*, 
      row_number() over (partition by number order by processed desc) as seqnum 
     from table t 
    ) 
delete from todelete 
    where seqnum > 1; 

row_number()枚舉行,使用處理作爲優先級。該邏輯可確保只剩一行,即使沒有任何行有processed = 1

+0

+1我喜歡這種方法。簡單而高效。我在這裏檢查http://sqlfiddle.com/#!3/925725/4 – 2014-10-20 10:36:30

+0

不錯的一個戈登,我做了與row_number相同的邏輯,但我想我複雜的整體語法 – mxix 2014-10-20 10:48:07

相關問題