1

重複したエントリを含むテーブルがあります。1 つを除いてすべて破棄してから、この最新のものを更新する必要があります。次のように、一時テーブルと while ステートメントを試しました。

CREATE TABLE #tmp_ImportedData_GenericData
(
    Id int identity(1,1),
    tmpCode varchar(255)  NULL,
    tmpAlpha3Code varchar(50)  NULL,
    tmpRelatedYear int NOT NULL,
    tmpPreviousValue varchar(255)  NULL,
    tmpGrowthRate varchar(255)  NULL
)

INSERT INTO #tmp_ImportedData_GenericData
SELECT
    MCS_ImportedData_GenericData.Code, 
MCS_ImportedData_GenericData.Alpha3Code,
MCS_ImportedData_GenericData.RelatedYear,
MCS_ImportedData_GenericData.PreviousValue,
MCS_ImportedData_GenericData.GrowthRate
FROM MCS_ImportedData_GenericData
INNER JOIN
(
    SELECT CODE, ALPHA3CODE, RELATEDYEAR, COUNT(*) AS NUMROWS
    FROM MCS_ImportedData_GenericData AS M
    GROUP BY M.CODE, M.ALPHA3CODE, M.RELATEDYEAR
    HAVING count(*) > 1
) AS M2 ON MCS_ImportedData_GenericData.CODE = M2.CODE
    AND MCS_ImportedData_GenericData.ALPHA3CODE = M2.ALPHA3CODE
    AND MCS_ImportedData_GenericData.RELATEDYEAR = M2.RELATEDYEAR
WHERE
(MCS_ImportedData_GenericData.PreviousValue <> 'INDEFINITO')

 -- SELECT * from #tmp_ImportedData_GenericData
 -- DROP TABLE #tmp_ImportedData_GenericData

DECLARE @counter int
DECLARE @rowsCount int

SET @counter = 1

SELECT @rowsCount =  count(*) from #tmp_ImportedData_GenericData
-- PRINT @rowsCount

WHILE @counter  < @rowsCount
BEGIN
    SELECT 
        @Code = tmpCode, 
        @Alpha3Code = tmpAlpha3Code, 
        @RelatedYear = tmpRelatedYear, 
        @OldValue = tmpPreviousValue, 
        @GrowthRate = tmpGrowthRate 
    FROM 
        #tmp_ImportedData_GenericData
    WHERE 
        Id = @counter

    DELETE FROM MCS_ImportedData_GenericData 
    WHERE 
        Code = @Code 
        AND Alpha3Code = @Alpha3Code  
        AND RelatedYear = @RelatedYear  
        AND PreviousValue <> 'INDEFINITO' OR PreviousValue IS NULL  

    UPDATE 
        MCS_ImportedData_GenericData 
        SET 
          PreviousValue = @OldValue, GrowthRate = @GrowthRate 
    WHERE 
        Code = @Code 
        AND Alpha3Code = @Alpha3Code  
        AND RelatedYear = @RelatedYear  
        AND MCS_ImportedData_GenericData.PreviousValue ='INDEFINITO'

    SET @counter = @counter + 1
END

しかし、処理する行が 20000 ~ 30000 行しかない場合でも、時間がかかりすぎます。

パフォーマンスを向上させるための提案はありますか?

前もって感謝します!

4

3 に答える 3

3
WITH q AS (
        SELECT  m.*, ROW_NUMBER() OVER (PARTITION BY CODE, ALPHA3CODE, RELATEDYEAR ORDER BY CASE WHEN PreviousValue = 'INDEFINITO' THEN 1 ELSE 0 END)
        FROM    MCS_ImportedData_GenericData m
        WHERE   PreviousValue <> 'INDEFINITO'
        )
DELETE
FROM    q
WHERE   rn > 1
于 2009-04-09T16:19:32.627 に答える
1

Quassnoiの答えはSQLServer2005+構文を使用しているので、もっと一般的なものを使用する価値のあるタペンスを入れると思いました...

まず、「元の」ではなくすべての重複を削除するには、重複するレコードを互いに区別する方法が必要です。(Quassnoiの回答のROW_NUMBER()部分)

あなたの場合、ソースデータにはID列がないように見えます(一時テーブルにID列を作成します)。その場合、私の頭に浮かぶ2つの選択肢があります
。1。ID列をデータに追加してから、重複を削除し
ます。2.「重複排除」データセットを作成し、元のデータからすべてを削除します。重複排除されたデータを元のデータに挿入し直します

オプション1は次のようになります...(新しく作成されたIDフィールドを使用)

DELETE
   [data]
FROM
   MCS_ImportedData_GenericData AS [data]
WHERE
   id > (
         SELECT
            MIN(id)
         FROM
            MCS_ImportedData_GenericData
         WHERE
            CODE = [data].CODE
            AND ALPHA3CODE = [data].ALPHA3CODE
            AND RELATEDYEAR = [data].RELATEDYEAR
        )

また...

DELETE
   [data]
FROM
   MCS_ImportedData_GenericData AS [data]
INNER JOIN
(
   SELECT
      MIN(id) AS [id],
      CODE,
      ALPHA3CODE,
      RELATEDYEAR
   FROM
      MCS_ImportedData_GenericData
   GROUP BY
      CODE,
      ALPHA3CODE,
      RELATEDYEAR
)
AS [original]
   ON [original].CODE = [data].CODE
   AND [original].ALPHA3CODE = [data].ALPHA3CODE
   AND [original].RELATEDYEAR = [data].RELATEDYEAR
   AND [original].id <> [data].id
于 2009-04-09T18:12:31.497 に答える
0

正確な答えを投稿するのに十分な使用済み構文を完全には理解していませんが、ここにアプローチがあります。

保存する行を特定します(たとえば、値を選択、... from .. where ...)

識別中に更新ロジックを実行します(たとえば、値+ 1 ... from ... where ...を選択します)

selectを新しいテーブルに挿入してください。

オリジナルを削除し、新しい名前をオリジナルに変更し、すべての許可/同義語/トリガー/インデックス/ FK / ...を再作成します(または、オリジナルを切り捨てて、新しいものから選択を挿入します)

明らかにこれにはかなり大きなオーバーヘッドがありますが、何百万もの行を更新/クリアしたい場合は、これが最速の方法になります。

于 2009-07-07T10:17:30.517 に答える