2013-05-26 59 views
4

考慮在SQL Server 2008中的以下數據庫表:SQL服務器 - 選擇行,刪除重複但保留一行最高日

ActionID (PK) ActionType ActionDate    UserID ContentID 
1    'Create'  '2013-05-26 18:40:00' 1  10 
2    'Create'  '2013-05-26 18:30:00' 2  10 
3    'Edit'  '2013-05-26 12:30:00' 5  12 
4    'Edit'  '2013-05-26 12:25:00' 5  12 
5    'Delete'  '2013-05-26 12:22:00' 6  12 

我想寫一個SQL查詢,通過ContentIDActionType但其中組與最新的ActionDate行將被返回並忽略其他行,即使它們具有不同的UserID或其他列值。

那麼它應該返回是:

ActionID (PK) ActionType ActionDate    UserID ContentID 
1    'Create'  '2013-05-26 18:40:00' 1  10 
3    'Edit'  '2013-05-26 12:30:00' 5  12 
5    'Delete'  '2013-05-26 12:22:00' 6  12 

但我不能完全弄清楚如何編寫查詢,以做到這一點。

回答

7

一種方法是使用CTE(公用表表達式)。

有了這個CTE,可以通過一些標準劃分您的數據 - 即你ContentIDActiontype - 並有從1開始爲每個「分區」,由ActionDate有序的SQL服務器數量的所有行。

因此,嘗試這樣的事:

;WITH Actions AS 
(
    SELECT 
     ActionID, ActionType, ActionDate, UserID, ContentID, 
     RowNum = ROW_NUMBER() OVER(PARTITION BY ContentID, ActionType ORDER BY ActionDate DESC) 
    FROM 
     dbo.YourTable 
    WHERE 
     ...... 
) 
SELECT 
    ActionID, ActionType, ActionDate, UserID, ContentID, 
FROM 
    Actions 
WHERE 
    RowNum = 1 
ORDER BY 
    ActionDate DESC 

請問這種方法,你在找什麼?

+0

它不會讓我堅持WITH操作位ORDER BY,但我可以把它放在後面的SELECT語句。我需要通過ActionDate列進行排序,那麼這將是一種有效的方式嗎? –

+2

@SundayIronfoot:只需將ORDER BY添加到選擇CTE中行的「外部」SELECT中(如我更新的響應所示) - 那就是你需要的嗎? –

3
select t1.* 
from Table1 t1 
inner join (select ContentID, ActionType, max(ActionDate) as MaxDate 
      from Table1 
      group by ContentID, ActionType) t2 
     on t1.ContentID = t2.ContentID 
     and t1.ActionType = t2.ActionType 
     and t1.ActionDate = t2.MaxDate; 

如果您有{ContentID,ActionType}對的重複行,那麼任何回答您問題的查詢都可能會產生意想不到的結果。