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 的记录,因为它们没有反映自上次价格更新以来的任何变化。

我确信它可以完成,尽管它可能需要几个步骤。需要明确的是,这个表已经膨胀到 100gb 并且包含 600M 行。我相信适当的清理将使该表的大小减少 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

我建议您使用 group by 查询重新创建表。另外,我假设“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

如果您想保留最新版本,请在 order by 子句中使用“timestamp desc”。

于 2012-05-11T14:02:53.220 回答