1.SELECT max(id) FROM (SELECT TOP 10 id FROM tablename)AS T
2.SELECT max(id) FROM (SELECT TOP 10 id FROM tablename order by id)AS T
上边第一句没有order by 的情况下 为什么 max(id) 出来的是全表中最大的ID值 而不是 子查询查出的前10条记录的最大值?

解决方案 »

  1.   

    第一句的子查询没有指定Top 10 的内容,是 MS 在Sql 里的机制 默认问题。
      

  2.   

    top 尽量和order by一起用,不然表中存储的物理次序是没法保证的
      

  3.   

    id 主键和标识列 数据库 sqlserver2005
      

  4.   

    SELECT TOP 10 id FROM tablename
    没有orderby的返回结果具有不确定性的。
      

  5.   

    但是我SELECT TOP 10 id FROM tablename 与SELECT TOP 10 id FROM tablename order by id 查询的结果是一致的,平时 top 是与order by一起用的,今天偶然发现这个问题。不明白,msdn也没查到资料,所以发上来向各位大虾请教。
      

  6.   

    msdn当然没有,因为集合没有所谓的顺序概念。没有order by的结果集叫集合。有order by的结果集叫游标。
      

  7.   

    SELECT TOP 10 id FROM tablename
    SELECT TOP 10 id FROM tablename order by id
    你确定子查询出来的是多少吗
      

  8.   


    5楼的解释很清楚。集合无顺序。一个查询,不指定ORDER BY,则返回顺序是不确定的。查询引擎会根据表的物理存储和查询计划查询数据并以最直接的方式输出,不同的语句有不同的查询计划,结果是不确定的。单独执行子查询SELECT TOP 10 id FROM tablename
    在外部查询中使用MAX
    SELECT TOP 10 id FROM tablename WHERE ...
    SELECT TOP 10 id FROM tablename INNER JOIN /LEFT JOIN ...
    这些情况,查询计划可能差别很大,返回结果的顺序自然也是不确定的。
      

  9.   

    一个查询的逻辑处理过程跟实际的物理执行过程可能完全不同。我猜LZ的id字段上有索引。SELECT TOP 10 id FROM tablename
    从表中随便查出10个id,则Index Scan取出前10条即可。1.SELECT max(id) FROM (SELECT TOP 10 id FROM tablename)AS T
    这个查询,逻辑上是先理解子查询,然后从子查询结果中查最大值。
    但查询引擎意识到这个查询是从表中随便查出10个id(因为没有ORDER BY),然后取最大值。那直接Index Scan从索引中取出id的最大值是最方便的。2.SELECT max(id) FROM (SELECT TOP 10 id FROM tablename order by id)AS T
    这个查询指定了ORDER BY,则必须是从表中按id的顺序取出前10个,再计算前10个的最大值。
      

  10.   

    为什么没有order by 的情况下 max会将全表记录做为求值范围… 看来目前我只有按照集合、优化这两个角度来理解了… 不过还是想求高手解释这两条sql语句执行原理。
      

  11.   

    打个比方:你手里拿着一本字典。字典中的单词是按字典序编排的。这是一个聚集索引。
    1.SELECT max(id) FROM (SELECT TOP 10 id FROM tablename)AS T
    从字典里随便找10个单词,告诉我最大的一个。
    既然是随便找10个,那你当然可以找最大的10个,你知道字典最后一个单词是最大的,直接返回。2.SELECT max(id) FROM (SELECT TOP 10 id FROM tablename order by id)AS T
    从字典里按顺序取出10个单词,告诉我最大的一个。
    那你只能老老实实地从头开始数10个,然后返回第10个(前10个中最大的)。