Как вы, вероятно, знаете, вы можете сделать это в более поздних версиях, используя row_number
очень просто.
delete t from
(select ROW_NUMBER() over (order by data) r from table1) t
where r in (2,5,6)
Даже без этого можно использовать недокументированную функцию %%LOCKRES%%
, чтобы различать 2 одинаковых строки
SELECT data,%%LOCKRES%%
FROM dbo.table1`
Я не думаю, что это доступно в SQL Server 2000, хотя.
В наборах SQL нет порядка, но у курсоров есть, чтобы вы могли использовать что-то вроде ниже. NB: Я ожидал, что смогу использовать DELETE ... WHERE CURRENT OF
, но это зависит от PK, поэтому код для удаления строки не так прост, как я надеялся.
В случае, если удаляемые данные являются дубликатами, нет гарантии, что они удалят ту же строку, что и CURRENT OF
. Однако в этом случае порядок связанных строк в любом случае является произвольным, поэтому любой удаляемый ряд мог бы с одинаковым успехом получить этот номер строки в порядке курсора.
DECLARE @RowsToDelete TABLE
(
rowidx INT PRIMARY KEY
)
INSERT INTO @RowsToDelete SELECT 2 UNION SELECT 5 UNION SELECT 6
DECLARE @PrevRowIdx int
DECLARE @CurrentRowIdx int
DECLARE @Offset int
SET @CurrentRowIdx = 1
DECLARE @data int
DECLARE ordered_cursor SCROLL CURSOR FOR
SELECT data
FROM dbo.table1
ORDER BY data
OPEN ordered_cursor
FETCH NEXT FROM ordered_cursor INTO @data
WHILE EXISTS(SELECT * FROM @RowsToDelete)
BEGIN
SET @PrevRowIdx = @CurrentRowIdx
SET @CurrentRowIdx = (SELECT TOP 1 rowidx FROM @RowsToDelete ORDER BY rowidx)
SET @Offset = @CurrentRowIdx - @PrevRowIdx
DELETE FROM @RowsToDelete WHERE rowidx = @CurrentRowIdx
FETCH RELATIVE @Offset FROM ordered_cursor INTO @data
/*Can't use DELETE ... WHERE CURRENT OF as here that requires a PK*/
SET ROWCOUNT 1
DELETE FROM dbo.table1 WHERE (data=@data OR data IS NULL OR @data IS NULL)
SET ROWCOUNT 0
END
CLOSE ordered_cursor
DEALLOCATE ordered_cursor