実行に数時間かかる TSQL ステートメントがあります。重複が挿入されるのを避けるために、インポート プロセスを調べる必要があると確信していますが、当面は、重複する値を持つレコードを除くすべてのレコードを削除したいと思います。ParameterValueId はテーブルの主キーですが、削除する必要がある重複したエントリが多数あります。ParameterId、SiteId、MeasurementDateTime、および ParameterValue ごとに 1 つのレコードのみが必要です。以下は、重複レコードを削除するための現在の方法です。It finds all values that have a count > 1. 次に、それらの値を持つ最初の Id を見つけ、それらの値で見つかった最初の ID と一致しない値を持つすべてのレコードを削除します。print ステートメント以外に、これを行うより効率的な方法があります。パフォーマンスを向上させるためにカーソルを使用する方法はありますか?
BEGIN TRANSACTION
SET NOCOUNT ON
DECLARE @BeginningRecordCount INT
SET @BeginningRecordCount =
(
SELECT COUNT(*)
FROM ParameterValues
)
DECLARE @ParameterId UNIQUEIDENTIFIER
DECLARE @SiteId UNIQUEIDENTIFIER
DECLARE @MeasurementDateTime DATETIME
DECLARE @ParameterValue FLOAT
DECLARE CDuplicateValues CURSOR FOR
SELECT
[ParameterId]
,[SiteId]
,[MeasurementDateTime]
,[ParameterValue]
FROM [ParameterValues]
GROUP BY
[ParameterId]
,[SiteId]
,[MeasurementDateTime]
,[ParameterValue]
HAVING COUNT(*) > 1
OPEN CDuplicateValues
FETCH NEXT FROM CDuplicateValues INTO
@ParameterId
,@SiteId
,@MeasurementDateTime
,@ParameterValue
DECLARE @FirstParameterValueId UNIQUEIDENTIFIER
DECLARE @DuplicateRecordsDeleting INT
WHILE @@FETCH_STATUS <> -1
BEGIN
SET @FirstParameterValueId =
(
SELECT TOP 1 ParameterValueId
FROM ParameterValues
WHERE
ParameterId = @ParameterId
AND SiteId = @SiteId
AND MeasurementDateTime = @MeasurementDateTime
AND ParameterValue = @ParameterValue
)
SET @DuplicateRecordsDeleting =
(
SELECT COUNT(*)
FROM ParameterValues
WHERE
ParameterId = @ParameterId
AND SiteId = @SiteId
AND MeasurementDateTime = @MeasurementDateTime
AND ParameterValue = @ParameterValue
AND ParameterValueId <> @FirstParameterValueId
)
PRINT 'DELETING ' + CAST(@DuplicateRecordsDeleting AS NVARCHAR(50))
+ ' records with values ParameterId : ' + CAST(@ParameterId AS NVARCHAR(50))
+ ', SiteId : ' + CAST (@SiteId AS NVARCHAR(50))
+ ', MeasurementDateTime : ' + CAST(@MeasurementDateTime AS NVARCHAR(50))
+ ', ParameterValue : ' + CAST(@ParameterValue AS NVARCHAR(50))
DELETE FROM ParameterValues
WHERE
ParameterId = @ParameterId
AND SiteId = @SiteId
AND MeasurementDateTime = @MeasurementDateTime
AND ParameterValue = @ParameterValue
AND ParameterValueId <> @FirstParameterValueId
FETCH NEXT FROM CDuplicateValues INTO
@ParameterId
,@SiteId
,@MeasurementDateTime
,@ParameterValue
END
CLOSE CDuplicateValues
DEALLOCATE CDuplicateValues
DECLARE @EndingRecordCount INT
SET @EndingRecordCount =
(
SELECT COUNT(*)
FROM ParameterValues
)
PRINT 'Beginning Record Count : ' + CAST(@BeginningRecordCount AS NVARCHAR(50))
PRINT 'Ending Record Count : ' + CAST(@EndingRecordCount AS NVARCHAR(50))
PRINT 'Total Records Deleted : ' + CAST((@BeginningRecordCount - @EndingRecordCount) AS NVARCHAR(50))
SET NOCOUNT OFF
PRINT 'RUN THE COMMIT OR ROLLBACK STATEMENT AFTER VERIFYING DATA.'
--COMMIT
--ROLLBACK