各种消灭“取31-40行数据”--取指定范围不连续id的解法和分析
2011-11-18 10:18 屠龙解牛 阅读(344) 评论(0) 编辑 收藏 举报
一般面试都会出这种“取指定范围的不连续id的数据”,这个在分页是有一些意义的,不过个人觉得面试应该更多是考察“道”,而不是奇技淫巧。不管怎样,总结一下t-sql中如何操作。
step 1 先建测试数据
View Code
1 USE Test
2 DROP TABLE test
3 CREATE TABLE test(
4 id INT,
5 VALUE INT)
6
7 DECLARE @id INT, @value INT
8 SET @id = 1
9 set @value =1
10
11
12 WHILE (@id<300)
13 BEGIN
14 INSERT INTO test
15 (
16 id,
17 [VALUE]
18 )
19 VALUES
20 (
21 @id,
22 @value
23
24 )
25
26 SET @id = @id + 2
27 SET @value = @id
28
29
30 END
31
32 SELECT * FROM test
这样就有了一个150行的样本空间。
step 2 solution
method1 sql2005提供了一个新函数 rowNumber。
可以利用此函数和with一起实现:
WITH TABLEwithConID
AS
(SELECT * ,ROW_NUMBER() OVER (ORDER BY value) AS ContinuousID FROM test)
select * FROM TABLEwithConID where ContinuousID BETWEEN 31 AND 40
在更早的版本,可以考虑以下方法
method2 子查询
select top 10 * from test where id not in( select top 30 Id from test order by Id asc ) order by id asc;
变种
select top 10 * from test
where id >
(SELECT MAX(id) FROM
(SELECT TOP 30 id FROM test ORDER BY id asc) t)
ORDER BY id asc
此种方法不利于阅读
既然有in,自然有exists的版本:
select top 10 * from test t
WHERE NOT EXISTS
(SELECT * from
(SELECT TOP 30 * FROM test ORDER BY id asc) t2
WHERE t2.id =t.id
)
此版本效率最差,因为采用的是相关子查询:主查询每遍历一条记录时,都要针对主查询的值执行子查询。
--只能想到这么多,如果有其他方法请留言,我补充进去--