我想删除表中最旧的条目并保留N行。这很简单。
DELETE TOP(1000) from TABLE ORDER BY [date] DESC
但我想删除基于User和EventType的行。因此,如果我们设置N = 50,我想保留每个用户和事件类型的最新50条记录。
我的表格如下:
API_eventLog
- uid (PK, int, not null)
- eventTypeID (FK, int, not null)
- userGUID (FK, uniqueIdentifier, not null)
- date (datetime, not null)
- ...
SO上有一个类似的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删除行。(即保留每个User和EventTypeID的2个最新行。
答案 0 :(得分:1)
以下查询应该模拟SQL Server 2000中的ROW_NUMBER函数。
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
。我更新了我的例子。
答案 1 :(得分:0)
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<=@i
-- 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<=@i