基于SQL中的多个列删除值的有效方法

时间:2014-03-10 15:12:17

标签: sql sql-server

我想根据两列的组合删除行。我的表看起来像这样(简化):

[ID], [Sub_ID], [Value] 

值可以是:

1234 - 1 - 100
1234 - 2 - 50
5678 - 1 - 90
4321 - 1 - 75
4321 - 2 - 75

我想删除除[ID]和[Sub_ID]的某些特定组合之外的所有记录。示例:删除除组合1234-2和4321-2之外的所有组合。

*编辑:这两个值是一个例子,实际上我需要保持超过10,000个ID-Sub_ID组合。

为此,我将两个ID列与强制转换组合在一起,并删除与此组合不匹配的所有内容。

Delete 
from table
    where   
    CAST(ID as varchar(4))+'-'+Cast(Sub_ID as varchar(1)) not in
    ('1234-2', '4321-2')

这有效,但速度很慢,可能非常低效。执行此查询已经花费了几分钟,我将每个月扩展选择,可能每次都更糟糕,有谁知道我如何才能提高效率?

非常感谢, 史蒂芬

4 个答案:

答案 0 :(得分:0)

您可以使用CTE选择所有不应删除的记录,然后您可以将其与原始表一起加入:

WITH Keep AS
(
    SELECT ID=1234, Sub_ID=2
      UNION ALL
    SELECT ID=4321, Sub_ID=2
)    
SELECT t.* 
FROM Table1 t INNER JOIN Keep k
  ON t.ID = k.ID AND t.Sub_ID = k.Sub_ID 

这显示了您要保留的内容:demo

如果您想删除另一个,可以使用NOT EXISTS

WITH Keep AS
(
    SELECT ID=1234, Sub_ID=2
      UNION ALL
    SELECT ID=4321, Sub_ID=2
)   
DELETE t FROM Table1 t WHERE NOT EXISTS
(
   SELECT 1 FROM Keep k 
   WHERE k.ID = t.ID AND k.Sub_ID = t.Sub_ID
)

Demo

这种方法应该高效且易读。

答案 1 :(得分:0)

在where子句的左侧执行转换通常会导致性能不佳。我建议在临时表中暂存要删除的行,然后在删除中简单地加入它。当您需要扩展删除条件时,只需在此临时表中添加一个插入(@delete):

declare @t table (ID int, Sub_ID int, Value int)
insert into @t 
    select 1234, 1, 100 union all
    select 1234, 2, 50 union all
    select 5678, 1, 90 union all
    select 4321, 1, 75 union all
    select 4321, 2, 75;


--stage the combination IDs you want to delete:
declare @delete table (ID int, Sub_ID int);
insert into @delete
    select 1234, 2 union all
    select 4321, 2;

delete  t
from    @t t
join    @delete d on 
        t.ID = d.ID and t.Sub_ID = d.Sub_ID;


select * from @t;

答案 2 :(得分:0)

不要将您的列组合并将它们转换为字符串,这会非常慢,因为您已经注意到了。使用以下内容过滤列本身:

DELETE FROM table WHERE {
  NOT((ID = x0 AND SUB_ID = y0) OR (ID = x1 AND SUB_ID = y1))

}

答案 3 :(得分:0)

该问题的可能解决方案:

  1. 看起来ID和SubID都是数字,所以不要比较字符串,而是比较数字。

  2. 创建包含ID和SubID

  3. 的索引
  4. DELETE是一个沉重的语句,需要大量的数据库写入,并且可能会使索引碎片化。如果表足够大并且您知道要删除整个表的至少三分之一,请使用临时表并执行INSERT ... SELECT语句以将REMAINING记录插入临时表。从主表中删除所有记录,然后切换表名。您通常需要在一次交易中完成。实施前的测试表性能。 示例:Bulk DELETE on SQL Server 2008 (Is there anything like Bulk Copy (bcp) for delete data?)