1

フィールド id、invid、vendorid、cost、timestamp、chdeleted を持つテーブル costhistory があります。ベンダーが価格リストを更新するたびに、トリガーが入力されたようです。

最後のレコード以降に価格が変更されたかどうかに関係なく入力されたため、冗長なレコードがあります。
例:

id | invid | vendorid | cost | timestamp | chdeleted  
1 | 123 | 1 | 100 | 1/1/01 | 0  
2 | 123 | 1 | 100 | 1/2/01 | 0  
3 | 123 | 1 | 100 | 1/3/01 | 0  
4 | 123 | 1 | 500 | 1/4/01 | 0  
5 | 123 | 1 | 500 | 1/5/01 | 0  
6 | 123 | 1 | 100 | 1/6/01 | 0

最後の価格更新以降の変更が反映されていないため、ID 2、3、5 のレコードを削除したいと思います。

いくつかの手順が必要になる場合がありますが、実行できると確信しています。明確にするために、このテーブルは 100 GB に膨れ上がり、6 億行が含まれています。適切なクリーンアップにより、このテーブルのサイズが 90% ~ 95% 縮小されると確信しています。

ありがとう!

4

2 に答える 2

3

採用するアプローチは、使用しているデータベースによって異なります。SQL Server 2005 以降の場合、次のクエリで削除するレコードが得られます。

select id 
from (
    select id, Rank() over (Partition BY invid, vendorid, cost order by timestamp) as Rank
    from costhistory 
) tmp
where Rank > 1

その後、次のように削除できます。

delete from costhistory 
where id in (
    select id 
    from (
        select id, Rank() over (Partition BY invid, vendorid, cost order by timestamp) as Rank
        from costhistory 
    ) tmp
)
于 2012-05-11T13:58:45.890 に答える
0

groupbyクエリを使用してテーブルを再作成することをお勧めします。また、「id」列は他のテーブルでは使用されていないと思います。その場合は、それらのテーブルも修正する必要があります。

このような大量のレコードを削除するには、長い時間がかかる可能性があります。

クエリは次のようになります。

insert into newversionoftable(invid, vendorid, cost, timestamp, chdeleted)
    select invid, vendorid, cost, timestamp, chdeleted
    from table
    group by invid, vendorid, cost, timestamp, chdeleted

削除を選択した場合は、次のことをお勧めします。

(1)最初にコードを修正して、重複が発生しないようにします。(2)重複IDを特定し、別のテーブルに配置します。(3)一括削除します。

重複するIDを見つけるには、次のようなものを使用します。

    select *
    from (select id,
                 row_number() over (partition by invid, vendorid, cost, timestamp, chdeleted order by timestamp) as seqnum
          from table
         ) t
    where seqnum > 1

代わりに最新バージョンを保持する場合は、orderby句で「timestampdesc」を使用します。

于 2012-05-11T14:02:53.220 に答える