Используйте ROW_NUMBER()
оконную функцию вместо RANK()
.Запросите это в CTE, затем просто DELETE
записи из CTE.Это вернется к вашему фактическому столу.
; WITH cte1 AS (
SELECT ROW_NUMBER() OVER ( PARTITION BY ID, LAST_MODIFIED_DATE ORDER BY ( SELECT NULL ) ) AS rn
FROM t1
)
DELETE FROM cte1 WHERE rn > 1 ;
https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=0b1e4bba4577837cf7c9cedbd26e3e36
Имейте в виду, что, если вы удалите много записей, вы значительно увеличите свой журнал и вам потребуется перестроить все имеющиеся у вас индексы.
Если вы ограничены в пространстве, ответ Гордона о выборе новой таблицы будет лучшим.Это будет зависеть от того, как будет выглядеть остальная часть таблицы.
Сколько строк мы работаем?И есть ли какие-либо индексы в данных?
РЕДАКТИРОВАТЬ ПРИМЕЧАНИЕ: Я изменил свою функцию ROW_NUMBER()
на ORDER BY ( SELECT NULL )
вместо фактического поля.В этом случае нам не важно, какой будет порядок, поскольку мы ищем дубликаты.
РЕДАКТИРОВАТЬ 2:
https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=1f3eb371dbe1cfa84291e5aaa566cc76
Эта ссылка демонстрирует наличие дополнительного столбца, который не позволит нам действительно дублировать строки.Но мы все еще можем удалять записи на основе ID
и LAST_MODIFIED_DATE
.Однако обратите внимание, что строки, которые считаются «дубликатами», будут несколько произвольными, если вы не укажете другое поле в ORDER BY ....
.