2013-12-23 45 views
0

我想刪除表中最舊的條目並保留N行。這很簡單。 刪除每個用戶的行數和保留N行的eventType

DELETE TOP(1000) from TABLE ORDER BY [date] DESC 

但我想刪除基於用戶和事件類型行。所以如果我們設置N = 50,我想保留每個用戶和EventType最新的50條記錄。

我的表是這樣的:

API_eventLog 
- uid (PK, int, not null) 
- eventTypeID (FK, int, not null) 
- userGUID (FK, uniqueIdentifier, not null) 
- date (datetime, not null) 
- ... 

有一個類似question已經在使具有以下的答案,但不幸的是它是SQL Server 2005

;WITH Dealers AS (
    SELECT *, 
    ROW_NUMBER() OVER(PARTITION BY DealerID ORDER BY SomeTimeStamp DESC) RowID 
    FROM MyDealersTable 
) 
DELETE 
FROM Dealers 
WHERE RowID > 50 

有在SQL Server 2000中具有良好性能的解決方案?我所能想到的只是一種基於遊標的解決方案,但這種方式會讓緩慢運行頻繁執行。

實施例的數據:

[uid] [EventTypeID] [userGUID] [date] 
1 1 5B1DCB9D-4EC7-4AAE-BEB1-DC1EA90EA06B 2013-11-17 
2 2 5B1DCB9D-4EC7-4AAE-BEB1-DC1EA90EA06B 2013-11-17 
3 3 5B1DCB9D-4EC7-4AAE-BEB1-DC1EA90EA06B 2013-11-18 
4 4 5B1DCB9D-4EC7-4AAE-BEB1-DC1EA90EA06B 2013-11-18 
5 1 5B1DCB9D-4EC7-4AAE-BEB1-DC1EA90EA06B 2013-11-19 
6 1 5B1DCB9D-4EC7-4AAE-BEB1-DC1EA90EA06B 2013-11-22 
7 1 17941D18-CC79-4C29-BBBA-9CBE60993E43 2013-11-06 
8 2 17941D18-CC79-4C29-BBBA-9CBE60993E43 2013-11-17 
9 3 17941D18-CC79-4C29-BBBA-9CBE60993E43 2013-12-01 
10 2 17941D18-CC79-4C29-BBBA-9CBE60993E43 2013-12-07 
11 2 17941D18-CC79-4C29-BBBA-9CBE60993E43 2013-12-18 
11 1 17941D18-CC79-4C29-BBBA-9CBE60993E43 2013-12-20 

在上述例子中,給定的N = 2,我想刪除行與[UID] 1和8(即,保持每個用戶和EventTypeID 2級最新的行。

+0

我想如果沒有光標或循環是possible.provide 2用戶each.you希望每個用戶保持每50個事件記錄或只有每用戶50 records.which是正確的至少10個樣本數據? – KumarHarsh

+0

表中有多少行?有多少不同的'User,EventType'組合? –

+0

@MartinSmith,我會保存表格每天增長1000到2000行。目前有10個用戶和30個eventTypes。預計用戶數量會增加。 – David

回答

1

下面的查詢應模擬SQL Server中的ROW_NUMBER函數2000

DELETE API_eventLog 
WHERE id IN 
    (SELECT 
    id 
    FROM API_eventLog AS a1 
    WHERE 
    (SELECT COUNT(1) 
     FROM API_eventLog AS a2 
     WHERE a2.userguid = a1.userguid 
     AND a2.eventTypeID = a1.eventTypeID 
     AND (a2.date > a1.date)) > 0); 
SELECT * FROM API_eventLog; 

0通過50或任何數量或行你更換想保持。

我不能在SQL Server 2000測試,但here是在SQL Server中的工作示例2008

編輯:

好像我犯了一個小錯誤。如果您想保留最新的行,日期檢查應該是greater than而不是less than。我更新了我的例子。

+0

謝謝,效果很好!非常快。 – David

0

對不起@David我不得不移動then.mine幾乎是相同的。我假設每個userGUID生成行號,每個事件類型日期升序。每個事件每個userGUID甚至在現實生活中可能不會有50個或更多行。在這種情況下,什麼?

Declare @API_eventLog table(uid int,EventTypeID int,userGUID uniqueIdentifier,date1 date) 
insert into @API_eventLog 
values(1, 1, '5B1DCB9D-4EC7-4AAE-BEB1-DC1EA90EA06B', '2013-11-17'), 
(2, 2, '5B1DCB9D-4EC7-4AAE-BEB1-DC1EA90EA06B', '2013-11-17'), 
(3, 3, '5B1DCB9D-4EC7-4AAE-BEB1-DC1EA90EA06B', '2013-11-18'), 
(4, 4, '5B1DCB9D-4EC7-4AAE-BEB1-DC1EA90EA06B', '2013-11-18'), 
(5, 1, '5B1DCB9D-4EC7-4AAE-BEB1-DC1EA90EA06B', '2013-11-19'), 
(6, 1, '5B1DCB9D-4EC7-4AAE-BEB1-DC1EA90EA06B', '2013-11-22'), 
(7, 1, '17941D18-CC79-4C29-BBBA-9CBE60993E43', '2013-11-06'), 
(8, 2, '17941D18-CC79-4C29-BBBA-9CBE60993E43', '2013-11-17'), 
(9, 3, '17941D18-CC79-4C29-BBBA-9CBE60993E43', '2013-12-01'), 
(10, 2, '17941D18-CC79-4C29-BBBA-9CBE60993E43', '2013-12-07'), 
(11, 2, '17941D18-CC79-4C29-BBBA-9CBE60993E43', '2013-12-18'), 
(11, 1, '17941D18-CC79-4C29-BBBA-9CBE60993E43', '2013-12-20') 



Declare @i int=1 
--you can test this other sample data 
select * from 
(select *, 
(select count(*) from @API_eventLog b where b.userGUID=a.userGUID and a.EventTypeID=b.EventTypeID and b.date1<=a.date1) rn 
from @API_eventLog a)t4 
where rn<[email protected] 

-- you can perform this 
delete from t4 from 
(select *, 
(select count(*) from @API_eventLog b where b.userGUID=a.userGUID and a.EventTypeID=b.EventTypeID and b.date1<=a.date1) rn 
from @API_eventLog a)t4 
where rn<[email protected]