“最优”的分页查询语句.求挑战。欢迎来喷

C丶先生 发布于 2013/07/25 15:16
阅读 1K+
收藏 3

本小学生刚学会sql语句。于是写了一个“最优”的分页查询。

select TOP @pagesize id,email,qq,wechart,phone,phone1 FROM contact
where id not in
(SELECT TOP (@pagesize*(currentpage-1)) id from contact ORDER BY id ASC )
ORDER BY id ASC

求超越。哈哈哈

加载中
1
54mark
54mark
CREATE PROCEDURE [dbo].[sp_Util_Page]
(
	@sField nvarchar(1000),		--字段(不可为空)
	@sTable nvarchar(1000),		--表名(不可为空)
	@sWhere nvarchar(1000),		--条件(可以为空,需要where)
	@sOrderby nvarchar(1000),	--排序(可以为空,需要order by,需要asc和desc字符)
	@sPkey nvarchar(50),		--主键(可以为空)
	@iPageIndex int,		--当前页数
	@iPageSize int,			--每页记录数
	@iRecordCount int OUTPUT,	--输出总记录条数(若<1则执行count)
	@sOutsql nvarchar(4000) OUTPUT	--输出sql语句
)
AS
BEGIN
	DECLARE @iRC int, @sSQL nvarchar(4000), @sW nvarchar(1000), @sOB nvarchar(1000), @sT nvarchar(100)
	SELECT @iRC = @iRecordCount, @sSQL = '', @sW = ' WHERE 1=1 ', @sOB = ' ORDER BY GETDATE() ASC '

	--判断条件
	IF RTRIM(@sWhere) != '' AND @sWhere IS NOT NULL
		BEGIN
			SET @sW=' ' + @sWhere + ' '
		END

	--判断总记录数
	IF @iRC<1
		BEGIN
			SET @sSQL='SELECT @iRC=Count(*) FROM ' + @sTable + @sW
			EXEC sp_executesql @sSQL,N'@iRC int OUT',@iRC OUT
		END

	--判断页数是否超出范围
	SELECT @iPageIndex=(CASE WHEN @iRC<(@iPageIndex-1)*@iPageSize THEN CEILING(@iRC/@iPageSize) WHEN @iPageIndex<1 THEN 1 ELSE @iPageIndex END)

	--判断排序
	IF RTRIM(@sOrderby) != '' AND @sOrderby IS NOT NULL
		BEGIN
			SELECT @sOB=' ' + @sOrderby + ' '
		END

	--如果是第一页
	IF @iPageIndex=1
		BEGIN
			SET @sSQL='SELECT TOP '+CAST(@iPageSize AS nvarchar)+' '+@sField+' FROM '+@sTable+@sW+@sOB
			GOTO step4
		END

	--看有否主键
	IF RTRIM(@sPkey) = '' OR @sPkey IS NULL
		GOTO step1
	ELSE
		--看是否按主键排序
		BEGIN
			DECLARE @sOB1 nvarchar(1000), @sPkey1 nvarchar(50)
			SELECT @sOB1 = UPPER(@sOrderby), @sPkey1 = UPPER(@sPkey)
			IF CHARINDEX(@sPkey1 + ' ASC', @sOB1)>0
				BEGIN
					SET @sT='>(SELECT MAX('
					GOTO step2
				END
			IF CHARINDEX(@sPkey1 + ' DESC', @sOB1)>0
				BEGIN
					SET @sT='<(SELECT MIN('
					GOTO step2
				END
			GOTO step3
		END

	--如果无主键
	step1:
		BEGIN
			DECLARE @max int, @min INT
			SET @max=@iPageIndex*@iPageSize
			SET @min=@max-@iPageSize
			SET @sSQL= 'SELECT ' + @sField + ' FROM ( '+'SELECT ' + @sField + ', ROW_NUMBER() OVER('+@sOB+') as _rn FROM '+@sTable+@sW+' ) _tmp WHERE _rn < '+cast(@max as nvarchar)+' and _rn >= '+cast(@min as nvarchar)
			GOTO step4
		END
	--纯按主键排序
	step2:
		BEGIN
			SET @sSQL='SELECT TOP '+CAST(@iPageSize AS nvarchar)+' '+@sField+' FROM '+@sTable+@sW
+' AND '+@sPkey+@sT+@sPkey+') FROM (SELECT TOP '+CAST((@iPageIndex-1)*@iPageSize AS nvarchar)+' '+@sPkey+' FROM '+@sTable+@sW+@sOB+') AS tbTemp)'+@sOB
			GOTO step4
		END
	--不纯按主键排序
	step3:
		BEGIN
			SET @sSQL='SELECT '+@sField+' FROM '+@sTable+@sW + ' AND ' + @sPkey+' IN (SELECT TOP '+CAST(@iPageSize AS nvarchar)+' '+@sPkey+' FROM '+@sTable+@sW + ' AND ' + @sPkey+' NOT IN(SELECT TOP '+CAST((@iPageIndex-1)*@iPageSize AS nvarchar)+' '+@sPkey+' FROM '+@sTable+@sW+@sOB+')'+@sOB+')'+@sOB
			GOTO step4
		END
	--输出最终执行的分页sql语句并执行
	step4:
		SELECT @sOutsql = @sSQL, @iRecordCount = @iRC
		--print(@sSQL)
		EXEC(@sSQL)
END
0
x
xeno

大言不惭,光是看到一个not in就不用看后面的了。

自己google下sql server的几种分页吧。

C丶先生
C丶先生
引号没看懂吗? 大神也写写呗。
0
amonxu
amonxu
看到标题我进来了,看到第一句我出去了。
0
C丶先生
C丶先生

真没有幽默感。

我其实只是想让各位也写一写。盖楼玩儿。诶。

0
IdleMan
IdleMan
给你100W数据,每页100rows,我要看9999页的数据,如果可以在10s内返回,那就确实牛逼
Null--Null
Null--Null
这条语言,应该不需要10s,我测试过,不过是每页10条,返回速度很快
0
赵亮-碧海情天
赵亮-碧海情天
开玩笑也不要开这样的玩笑啊,太冷了。
0
0
_凤求凰_
_凤求凰_
not in。。哈哈。。
返回顶部
顶部