2013-10-10 33 views
2

最大的一組我有一個表與下面的模式記錄:如何刪除不從SQL表

ID NVARCHAR(10) 
Message NVARCHAR(300) 
UpdateTime DATETIME 

其中ID是外鍵。新的郵件記錄將以相同的UpdateTime添加到羣集中。一個例子是(由IDUpdateTime排序):

ID | Status  | UpdateTime 
--------------------------------- 
42  Cluster1-Msg1 2012-12-25 
42  Cluster1-Msg2 2012-12-25 
42  Cluster2-Msg1 2013-10-10 
42  Cluster2-Msg2 2013-10-10 
43  Cluster4-Msg1 2011-11-27 

這裏ID#42與4個消息,在兩個組在不同的日期集羣相關聯,而ID#43僅與一個消息相關聯。

有時候我希望通過清除這張表,對於每個具有相同ID的組,刪除所有其組UpdateTime小於該組內最大值的消息記錄。最終的結果在上面的例子是:

42  Cluster2-Msg1 2013-10-10 
42  Cluster2-Msg2 2013-10-10 
43  Cluster4-Msg1 2011-11-27 

下面的SQL查詢查找所有我想要刪除的記錄:

SELECT Msgs.ID, Msgs.UpdateTime 
FROM Messages Msgs 
JOIN 
(SELECT ID, MAX(UpdateTime) AS MaxTime FROM Messages GROUP BY ID) MaxTimes 
ON Msgs.ID = MaxDates.ID 
WHERE Msgs.UpdateTime < MaxTimes.MaxTime 

現在,我希望寫一個DELETE語句刪除項匹配上面查詢返回的結果。該 記錄必須根據IDUpdateTime值被刪除。我只是不理解如何在Transact-SQL中表達這一點。

+0

如果你有重複?你想保持兩個還是隻有一個? – Paparazzi

+0

將表看作包含消息組(組密鑰是ID列)。我想刪除任何「舊」消息,即每個組中的日期少於最大日期的消息。 –

+0

你也可以使用'ROW_NUMBER'來做到這一點。 –

回答

4
DELETE Msgs 
FROM Messages Msgs 
JOIN (SELECT ID, MAX(UpdateTime) AS MaxTime FROM Messages GROUP BY ID) MaxTimes 
    ON Msgs.ID = MaxDates.ID 
WHERE Msgs.UpdateTime < MaxTimes.MaxTime 

注意,我所做的,這是複製原始的SELECT語句,而第一行代碼更改從SELECT ...DELETE Msgs。您必須指定表名,因爲查詢的FROM部分中有多個表表達式。

+0

就驗證了這一點在我的機器上。作品一種享受。感謝您的及時答覆! –

1
DELETE DUB 
FROM Messages AS DUB 
WHERE EXISTS (
      SELECT SUB.ID 
      FROM Messages AS SUB 
      WHERE SUB.ID = DUB.ID 
      GROUP BY SUB.ID 
      HAVING MAX(SUB.UpdateTime) > DUB.UpdateTime 
     ) 

我覺得這種相關的子查詢更具可讀性。