2014-05-06 115 views
4

說我有此表SQL刪除與重複的值的行,同時保持一個

id | data | value 
----------------- 
1 | a | A 
2 | a | A 
3 | a | A 
4 | a | B 
5 | b | C 
6 | c | A 
7 | c | C 
8 | c | C 

我想刪除與重複的值的那些行的每個數據,同時保持與所述最小ID的一個,例如其結果將是

id | data | value 
----------------- 
1 | a | A 
4 | a | B 
5 | b | C 
6 | c | A 
7 | c | C 

我知道一個辦法做到這一點是做一個聯盟,如:

SELECT 1 [id], 'a' [data], 'A' [value] INTO #test UNION SELECT 2, 'a', 'A' 
UNION SELECT 3, 'a', 'A' UNION SELECT 4, 'a', 'B' 
UNION SELECT 5, 'b', 'C' UNION SELECT 6, 'c', 'A' 
UNION SELECT 7, 'c', 'C' UNION SELECT 8, 'c', 'C' 

SELECT * FROM #test WHERE id NOT IN (
    SELECT MIN(id) FROM #test 
    GROUP BY [data], [value] 
    HAVING COUNT(1) > 1 
    UNION 
    SELECT MIN(id) FROM #test 
    GROUP BY [data], [value] 
    HAVING COUNT(1) <= 1 
) 

但這種解決方案有通過兩次重複同一組(考慮到實際情況是大於20列的羣組)

對於複雜的問題,我寧願用較少的代碼來簡化答案。有沒有更簡潔的方法來編碼?

謝謝

回答

12

兩種選擇:

  1. 使用WITH CTE

    WITH CTE AS 
    (SELECT *,RN=ROW_NUMBER() OVER(PARTITION BY data,value ORDER BY id) 
    FROM TableName) 
    DELETE FROM CTE WHERE RN>1 
    

    說明:

    這個查詢將選擇表的內容與沿行號RN。然後刪除RN> 1(這將是重複項)的記錄。

    This Fiddle顯示將要使用此方法刪除的記錄。

  2. 使用NOT IN

    DELETE FROM TableName 
    WHERE id NOT IN 
         (SELECT MIN(id) as id 
         FROM TableName 
         GROUP BY data,value) 
    

    說明:

    在給定的例子中,內部查詢將返回的ID(1,6,4,5,7)。外部查詢將刪除表號爲NOT IN(1,6,4,5,7)的表中的記錄。

    This fiddle顯示將要使用此方法刪除的記錄。

我的建議:我會去的第一個方法,因爲它比後者多了一個速度更快。

+0

這真是太棒了!只有一位SQL專家纔能有這樣出色的心態,謝謝! – user1589188

+0

@ user1589188:很高興,我的朋友。也增加了小提琴的例子。 –

相關問題