2017-08-22 96 views
0

我一直在使用下面的繼承查詢,我試圖刪除重複的行,當我第一次運行它時,我得到了一些意想不到的結果 - 我相信這跟我對於我的缺乏理解有關聲明的分區部分:SQL Server - 刪除重複行 - Partition By如何影響此查詢?

WITH CTE AS(
    SELECT [Id], 
    [Url], 
    [Identifier], 
    [Name], 
    [Entity], 
    [DOB], 
     RN = ROW_NUMBER()OVER(PARTITION BY Name ORDER BY Name) 
    FROM Data.Statistics 
    where Id = 2170 
) 
DELETE FROM CTE WHERE RN > 1 

有人可以幫助我明白我在做什麼與分區BY名稱這部分?這不會以任何方式限制查詢只在名稱字段中查找重複項,對嗎?我需要確保它正在查找記錄,其中CTE定義內的字段的所有5都是相同的,以使記錄被認爲是重複的。

+1

然後,您需要將所有5添加到'partition by',因爲您當前的查詢只檢查重複的'name'。如果你想預覽,只需要將'delete'改爲'select'。 – SqlZim

+0

謝謝@SqlZim。我知道將它作爲SELECT運行 - 這就是我所期望的奇怪結果。我編輯了我的帖子,以便更清楚地瞭解這一點。感謝您的信息。 – Stpete111

+2

將「分區依據」視爲與「分組依據」類似可能會有所幫助 - 您爲每組分區的列獲得不同組的行號。 – ZLK

回答

1

ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Name)沒有什麼意義。您不會ORDER BYPARTITION BY中使用的相同,因爲它將與分區中的所有內容相同,因此ORDER BY部分無用。

基本上這個查詢的CTE部分是說將臨時行(具有[Id] = 2170的那些行)分割爲每個不同名稱的組,並且在每個具有相同名稱的行組中,按名稱排序(顯然它們都是相同的值),然後返回該序列組中的行號爲RN。唯一名稱的行號都爲1,因爲只有一行具有該名稱。重複的名稱將包含行號1,2,3等。在這種情況下,這些行的順序是不確定的,因爲ORDER BY子句是愚蠢的,但如果您將ORDER BY更改爲有意義的行,則行號將遵循該順序。

+0

蒂姆。措辭措辭很好,易於理解。謝謝你。我已經標記爲答案。 – Stpete111

+0

嘿@Tim一個後續問題 - 你能否給我一個可以用來代替ORDER BY的例子來更有意義? – Stpete111

+1

例如,如果您有一個記錄創建日期,並且您希望保留最舊的記錄並刪除較新的重複記錄,那麼您將使用'ROW_NUMBER(PARTITION BY Name ORDER BY CreationDate)'來分配名稱行號的最舊記錄1,而下一個最早的將是第2行等。外部查詢刪除第1行以外的所有行。 – Tim