日期:2014-05-16  浏览次数:20450 次

最近面试遇到了很奇葩的事情
至少碰到3,4次了,在笔试的时候遇到过这样的一道题,题目类型一模一样,连里面的数据都是一模一样。。
难道网上有这道题目?还是说这是一道经典的题目??????

题目
从表中取出第31条到第40条数据,其中ID列自增加,且不一定连续。

这道题其实是考  row_number的用法。增加新的列用于标号。。然后取 31到40即可。。

其实我还想到一个自己觉得更好的方法
select top 40  *  from table
except
select top 30  *  from table


只是觉得为何如此的巧合。。很多面试官水平也不咋样,还觉得我第二种做法是乱写,以为我不会。
明明就自己不知道,而且太主观了。。好像只能用row_number一样。。这题出的。。。
------解决方案--------------------
没主键的情况
--首先,生成带记录号的临时表
select?id=identity(int,1,1),*?into?#temp

--然后,就可以用下面的语句检索出第M到N条记录:
select?*?from?#temp?where?id?between?m?and?n


2.有主键的情况
检索出第m页,每页共n条记录的语句

select?top?n?from?你的表?where?主键?not?in(select?(m-1)?*?n?主键?from?你的表)
m,n均为常量,不能为变量

------解决方案--------------------
你的方法:

select top 40  *  from table
except
select top 30  *  from table

虽然想法不错,但是是有问题的,为什么呢?

因为你用的是*,就是所有的列,问题是select top 40  *  from table 和 select top 30  *  from table,

 除了id列可以相减,其他列由于不一样,所以没办法进行except集合相减的,所以如果id是主键,不重复的,那么按照你的思路,可以这样:

select tt.*
from 
(
select top 40  id  from table
except
select top 30  id  from table
)t
inner join table tt on tt.id = t.id

------解决方案--------------------

not in
row_number

------解决方案--------------------
怎么看,那么像考分页的、、、