2010-06-16 36 views
7

基本上我想这样做:请解释这个删除前100名的SQL语法

delete top(100) from table order by id asc 

但MS SQL不允许在这个位置

常见的解决办法似乎是这个顺序:

DELETE table WHERE id IN(SELECT TOP (100) id FROM table ORDER BY id asc) 

但是我也发现这个方法here

delete table from (select top (100) * from table order by id asc) table 

它有一个更好的估计执行计划(74:26)。不幸的是我不太懂语法,请有人向我解释一下吗?

对任何其他方法始终感兴趣,以达到相同的结果。

编辑︰我仍然没有得到它我害怕,我希望能够阅读查询,因为我读了前两个实际上是英语。上述查询我是:

delete the top 100 records from table, with the records ordered by id ascending 
delete the top 100 records from table where id is anyone of (this lot of ids) 
delete table from (this lot of records) table 

我不能改变第三个成一个逻辑的英语句子......我想我想要知道的是,这如何转成“从表中删除(这很多记录)“。 'from'似乎处于不合逻辑的地位,第二次提到'table'在逻辑上是多余的(对我来说)。

回答

2

delete命令需要几个类似的形式,为from关键字是可选的,删除表中可以选择的记录中指定的查询分开:

delete table where ... 

delete from table where ... 

delete table from <query...> 

delete from table from <query...> 

与过去两年的人的想法是,您可以先定义要从哪个表中删除,然后您可以指定一个查询来挑选要删除的记录。查询可以加入到其他表中,这就是为什么您需要单独定义从哪个表中删除。

您发现的查询只是使用子查询来挑选要删除的记录。

+0

我无法企及你4个语法与第三例子读我为“从子表表中删除表”中的一个。请参阅我的编辑问题。 – Patrick 2010-06-16 13:29:51

+0

@Patrick:你可以在你的查询中添加可选的'from'(上面的第3个和第4个表格之间的区别),以使其更符合逻辑地阅读。我调整了上述表格以便更具描述性。 – Guffa 2010-06-16 14:49:23

+0

@Patrick:查询可以用英语描述为“从表中删除所有匹配记录的记录(这个记录称为'表')。”请注意,查询中的最后一个“表”是别名,而不是表的实际名称。 – Guffa 2010-06-16 15:01:16

5

这很好地解释here(约使用视图中的文章会谈,但我相信同样的逻辑必须适用于你的查询,如果你得到一个更好的执行计划)

第一个读取“删除“ 表的两部分。一旦确定 要删除的行,然后再一次 执行删除。

第二个避免这一点。

编辑这似乎更多的是关于语法的问题。删除的语法是described here

相关位的

DELETE 
    [ FROM ] 
    { <object> | rowset_function_limited 
    } 
    [ FROM <table_source> [ ,...n ] ] 

您的查询

delete alias 
from 
    (select top (100) * 
    from table 
    order by id asc) alias 

您使用的派生表,所以需要FROM <table_source>。您正在省略第一个可选的FROM。