类型:转载 责任编辑:asp.net 日期:2007/05/23
热门软件下载:
一直以来,使用一下存储过程实现搜索和分页以及排序。因为以前只用到了两个字段排序,而这两个字段都是唯一值字段。所以效率很好。也很完美。
今日因为需求。增加排序字段。这次按照访问次数排序。 因为此字段有重复记录存在。
那么该存储过程便出现了BUG。
即,如果下一页有排序字段值和上页最后一条的该字段值相等时则被过滤掉:原因如下:
IF @OrderType != 0
BEGIN
SET @strTmp = "<(select min"
SET @strOrder = " order by [" + @fldName +"] desc"
END
ELSE
BEGIN
SET @strTmp = ">(select max"
SET @strOrder = " order by [" + @fldName +"] asc"
END
寻思很久都无解决办法。用游标方法也存在以上问题。寻求解决办法。谢谢!
/*
时间:2004年10月11日
作者:Jon_zhu
备注:获得会员列表
如果您使用此存储过程方法只需要修改几个地方:
1、更改定义你的搜索条件参数。
2、更改构造你的查询条件。
3、更改定义表名和关键字段名
*/
CREATE PROCEDURE Member_GetMemberList
--定义搜索条件参数
@RecordID VARCHAR(15) = , --编号(精确)
@UserID VARCHAR(20) = , --用户名(精确)
@Province VARCHAR(15) = , --省份编号(精确)
@City VARCHAR(15) = , --城市编号(精确)
@Company VARCHAR(50) = , --公司名(模糊)
@Calling VARCHAR(15) = , --行业编号(精确)
@Status INT = , --状态(精确)
@Level INT = , --等级(精确)
@StartDate1 VARCHAR(100) = , --开始日期一(时间段)
@StartDate2 VARCHAR(100) = , --开始日期二(时间段)
@EndDate1 VARCHAR(100) = , --结束日期一(时间段)
@EndDate2 VARCHAR(100) = , --结束日期二(时间段)
--定义分页参数
@OrderType INT= 0, --设置排序类型, 非 0 值则降序, 0则为升序
@OrderName VARCHAR(20) = , --设置排序字段
@PageIndex INT= 0, --页码
@PageSize INT= 0, --页尺寸
@PageCount INT= 0 OUTPUT, --返回的页数
@RecordCount INT= 0 OUTPUT --返回的记录数
AS
DECLARE @tblName VARCHAR(20), @orderField VARCHAR(20), @fldName VARCHAR(20), @strWhere VARCHAR(1000)
SET @tblName="UserAccount" --定义表名
IF @OrderName= --定义排序字段名
SET @fldName="usac_serial"
ELSE
SET @fldName=@OrderName
--SET @fldName="usac_serial" --定义关键字段名
--定义构造查询条件
SET @strWhere=
IF @RecordID<>
SET @strWhere=@strWhere + AND usac_id= + CHAR(39) + @RecordID + CHAR(39)
IF @UserID<>
SET @strWhere=@strWhere + AND usac_userid= + CHAR(39) + @UserID + CHAR(39)
IF @Province<>
SET @strWhere=@strWhere + AND usac_province= + CHAR(39) + @Province + CHAR(39)
IF @City<>
SET @strWhere=@strWhere + AND usac_city= + CHAR(39) + @City + CHAR(39)
IF @Company<>
SET @strWhere=@strWhere + AND usac_company LIKE + CHAR(39) + % + @Company + % + CHAR(39)
IF @Calling<>
SET @strWhere=@strWhere + AND usac_calling= + CHAR(39) + @Calling + CHAR(39)
IF @Status<>
SET @strWhere=@strWhere + AND usac_status= + CAST(@Status AS VARCHAR)
IF @Level<>
SET @strWhere=@strWhere + AND usac_level= + CAST(@Level AS VARCHAR)
IF @StartDate1<> AND @StartDate2<>
SET @strWhere=@strWhere + AND usac_startdate BETWEEN + CHAR(39) + @StartDate1 + CHAR(39) + AND + CHAR(39) + @StartDate2 + CHAR(39)
IF @EndDate1<> AND @EndDate2<>
SET @strWhere=@strWhere + AND usac_startdate BETWEEN + CHAR(39) + @EndDate1 + CHAR(39) + AND + CHAR(39) + @EndDate2 + CHAR(39)
IF @strWhere<>
SET @strWhere=RIGHT(@strWhere,LEN(@strWhere) - 5)
--计算记录总数
IF ISNULL(@PageCount,0)<=0
BEGIN
DECLARE @countsql nvarchar(500)
IF @strWhere !=
SET @countsql=SELECT @RecordCount=COUNT(*) FROM + @tblName + WHERE + @strWhere
ELSE
SET @countsql=SELECT @RecordCount=COUNT(*) FROM + @tblName
EXEC SP_EXECUTESQL @countsql,N@RecordCount int out ,@RecordCount out
--求总页数
SET @PageCount = FLOOR(CAST(@RecordCount AS FLOAT) / @PageSize)
IF @PageCount < CAST(@RecordCount AS FLOAT) / @PageSize
SET @PageCount=@PageCount+1
END
DECLARE @strSQL varchar(6000) -- 主语句
DECLARE @strTmp varchar(500) -- 临时变量
DECLARE @strOrder varchar(500) -- 排序类型
--如果需要排序
IF @OrderType != 0
BEGIN
SET @strTmp = "<(select min"
SET @strOrder = " order by [" + @fldName +"] desc"
END
ELSE
BEGIN
SET @strTmp = ">(select max"
SET @strOrder = " order by [" + @fldName +"] asc"
END
--定义SQL语句
SET @strSQL = "select top " + STR(@PageSize) + " * from ["
+ @tblName + "] where [" + @fldName + "]" + @strTmp + "(["
+ @fldName + "]) from (select top " + STR((@PageIndex-1)*@PageSize) + " ["
+ @fldName + "] from [" + @tblName + "]" + @strOrder + ") as tblTmp)"
+ @strOrder
--如果查询条件不为空
IF @strWhere !=
SET @strSQL = "select top " + STR(@PageSize) + " * from ["
+ @tblName + "] where [" + @fldName + "]" + @strTmp + "(["
+ @fldName + "]) from (select top " + STR((@PageIndex-1)*@PageSize) + " ["
+ @fldName + "] from [" + @tblName + "] where " + @strWhere + " "
+ @strOrder + ") as tblTmp) and " + @strWhere + " " + @strOrder
--如果是第一页
IF @PageIndex = 1
BEGIN
SET @strTmp = ""
IF @strWhere !=
SET @strTmp = " where " + @strWhere
SET @strSQL = "select top " + STR(@PageSize) + " * from ["
+ @tblName + "]" + @strTmp + " " + @strOrder
END
EXEC (@strSQL)
RETURN @@ROWCOUNT
GO
网友回答:
参考
select top 10 * from t1 where id not in(select top (PageSize-1)*10 id from t1 order by id asc) order by id asc
前提是id是唯一字段。
when 客户选择访问次数排序,
use
order by 次数, 编号
and remember the last 编号 you used too
同意思归,你也可以使用一个临时表。
gz
are you sure your sql is correct? check the results in query analyzer
SELECT *
FROM User_BaseInfo
WHERE (PKId = ANY
(SELECT TOP 10 PKId
FROM User_BaseInfo
WHERE PKId IN
(SELECT TOP 30 PKId
FROM User_BaseInfo
ORDER BY UserName DESC, PKId)
ORDER BY UserName, PKId DESC))
ORDER BY UserName DESC, PKId
这也是一种分页方法,现在是每页10条记录,当前是第3页
frankly, no, I am just suspecting, see this subquery doesnt even have a where clause
AND (usac_serial in (select top 10 usac_serial from UserAccount
order by usac_times desc,usac_serial desc))
try to index usac_times