2013-06-05 92 views
3

我在表中有重複記錄。我需要能夠識別唯一的唯一標識符,所以我可以從表中刪除它。如何識別重複記錄的唯一標識符?

我知道有一個重複的唯一方法是從列subjectdescription所以如果至少有2個相同的主題和相同的描述,我需要刪除一個,並留下一個。

所以我能夠得到重複記錄的列表,但我無法獲得唯一標識符以便能夠刪除它。

這是我所做的識別重複記錄。

SELECT 
    p.accountid, p.subject, p.description, count(*) AS total 
FROM 
    activities AS p 
WHERE  
    (p.StateCode = 1) AND p.createdon >= getdate()-6 
GROUP BY 
    p.accountid, p.subject, p.description 
HAVING 
    count(*) > 1 
ORDER BY 
    p.accountid 

有一列record_id其中包含每個記錄的唯一標識符。但如果我在我的select語句中添加了record_id,那麼我得不到結果,因爲它不可能具有重複的唯一標識符

如何使用SQL Server獲得record_id

注:RECORD_ID不是一個整數,它是像 「D32B275B-0B2F-4FF6-8089-00000FDA9E8E」

感謝

回答

4

一個不錯的功能,我喜歡SQL Server與updatedelete語句使用熱膨脹係數的。

您正在查找重複記錄,並且可能想保留最低或最高的record_id。你可以得到的計數和ID使用CTE和窗口功能,以保持:

with todelete as (
    SELECT p.accountid, p.subject, p.description, 
      COUNT(*) over (partition by p.accountid, p.subject, p.description) as total, 
      MIN(record_id) over (partition by p.accountid, p.subject, p.description) as IdToKeep 
    FROM activities AS p 
    WHERE (p.StateCode = 1) AND p.createdon >= getdate()-6 
    ) 
delete from todelete 
    where total > 1 and record_id <> IdToKeep; 

最後where條款只是用邏輯來選擇合適的行刪除。

我要補充,如果你只是想將被刪除的列表,你可以使用類似的查詢:

with todelete as (
    SELECT p.accountid, p.subject, p.description, 
      COUNT(*) over (partition by p.accountid, p.subject, p.description) as total, 
      MIN(record_id) over (partition by p.accountid, p.subject, p.description) as IdToKeep 
    FROM activities AS p 
    WHERE (p.StateCode = 1) AND p.createdon >= getdate()-6 
    ) 
select * 
from todelete 
where total > 1 and record_id <> IdToKeep; 

over功能指示功能正被用作窗口函數。這個想法很簡單。 Count(*) over返回partition子句中字段值相同的所有記錄的計數。這與聚合函數非常相似,不同之處在於您可以獲得每一行的值。這個類的功能非常強大,我建議你多瞭解它們。

+0

謝謝你的回答,但RECORD_ID不是整數它是什麼:

;with recordsToDelete as ( SELECT recordId ,Row_Number() OVER(partition p.subject, p.description) as rowNum FROM activities AS p ) select * from recordsToDelete where rowNum > 1 

如果這看起來是正確的,你可以將其替換選擇像這樣「D32B275B-0B2F-4FF6-8089-00000FDA9E8E」我得到這個錯誤與第二個代碼操作數數據類型uniqueidentifier對於最小操作符無效。 – Mike

+0

@Mike。 。 。在這種情況下,你可以使用'MIN(cast(record_id as varchar(255)))。 。 .'。 MIN()會返回一個任意的值來保存。那是問題嗎?如果是這樣,你將如何選擇記錄ID保留哪些? –

+0

非常感謝你的工作,但是請你向我解釋一下幹什麼和分區?謝謝 – Mike

0

也許這樣的事情?

SELECT max(p.record_id), p.accountid, p.subject, p.description, count(*) AS total 
FROM activities AS p 
WHERE (p.StateCode = 1) AND p.createdon >= getdate()-6 
GROUP BY p.accountid, p.subject, p.description 
HAVING count(*) > 1 
ORDER BY p.accountid 
0

對我來說,你需要先做一個內部查詢,然後連接到較大的表來獲得你想要的。

SELECT ALL 
    * 
FROM (SELECT p.accountid 
    FROM activities AS p 
    WHERE p.statecode = 1 AND p.createdon >= getdate()-6 
    GROUP BY p.accountid 
    HAVING count(*) > 1) AS x 
JOIN activities AS a ON x.accountid = a.accountid 
ORDER BY p.accountid 
0

試試這個:

delete from recordsToDelete 
    where rowNum > 1