在我的使用SQL Server2005的新函数构造分页存储过程中,我提到了使用ROW_NUMBER()函数来代替top实现分页存储过程,
分页存储过程(二)在sqlserver中返回更加准确的分页结果
。但是时间长了,又发现了新问题,就是主子表的分页查询。例如:订单表和订单明细表,要求是查询订单,第二页,每页10条
复制代码代码如下:
--使用row_unmber()实现分页
--本来我们想要的结果是10条订单,结果却不是10条订单,而是10条明细
--其实是针对的子表进行分页了,订单并不是要显示的个数,出来的个数是明细的个数
--就是因为主表和子表联合查询的结果,主表记录和子表记录是1:N的关系,一个主表记录有多个明细
select * from
(SELECT ROW_NUMBER () OVER (ORDER BY oi.createdate DESC) AS rownumber,oi.orderseqno ,od.OrderDetailID
FROM OrderInfo oi LEFT JOIN OrderDetail od ON oi.OrderSeqNO=od.OrderSeqNO
WHERE oi.OrderSeqNO LIKE '%2%'
) AS o
WHERE rownumber BETWEEN 10 AND 20
结果如下图
很明显不是10条订单,而是10条明细。
下面是对查询的一点改进,使用了游标
复制代码代码如下:
--解决上面的问题,有以下几种办法
--1、先根据条件查询主表记录,然后在C#代码中循环,再次到数据库查询每条主表记录的明细信息,然后赋值给属性
--2、在数据库的存储过程中使用游标,也是先查询主表记录,然后使用游标循环的过程中,查询子表信息,然后在C#中
--集中处理
--很显然,后一种减少了数据库的往来开销,一次获取了想要的数据,个人认为要比第一种好,欢迎大家一起讨论更好的办法
--需要注意的就是ROW_NUMBER()返回的类型是bigint,而不是int
--下面是游标的存储过程
--建立主表临时表
CREATE TABLE #temp
(
rownumber bigint,
orderseqno VARCHAR(36),
goodsname VARCHAR(50),
companyname VARCHAR(100)
)
--建立子表临时表
CREATE TABLE #detail
(
orderseqno VARCHAR(36),
detailid UNIQUEIDENTIFIER,
unitprice DECIMAL(12,2),
Qty int
)
--插入主表数据到主表临时表
insert into #temp
SELECT oo.rownumber, oo.OrderSeqNO, oo.GoodsName, oo.CompanyName FROM
(SELECT ROW_NUMBER () OVER (ORDER BY oi.createdate DESC) AS rownumber,
oi.OrderSeqNO, oi.GoodsName ,ci.CompanyName
FROM OrderInfo oi INNER JOIN CompanyInfo ci ON oi.CompanyID=ci.CompanyID
WHERE oi.CreateDate ) AS oo WHERE rownumber BETWEEN 10 AND 20 --定义游标 DECLARE @temp_cursor CURSOR --给游标赋值 SET @temp_cursor=CURSOR FOR SELECT #temp.orderseqno,#temp.goodsname FROM #temp --定义游标循环过程中所需保存的临时数据 DECLARE @orderseqno VARCHAR(36),@goodsname varchar(50) --打开游标 OPEN @temp_cursor FETCH NEXT FROM @temp_cursor INTO @orderseqno,@goodsname --循环游标,查询子表数据,然后插入子表临时表 WHILE @@FETCH_STATUS=0 BEGIN INSERT INTO #detail SELECT od.OrderSeqNO,od.OrderDetailID, od.UnitPrice,od.Qty FROM OrderDetail od WHERE od.OrderSeqNO=@orderseqno FETCH NEXT FROM @temp_cursor INTO @orderseqno,@goodsname END --关闭游标 CLOSE @temp_cursor DEALLOCATE @temp_cursor SELECT * FROM #temp SELECT * FROM #detail --删除临时表 DROP TABLE #temp DROP TABLE #detail 结果如下图,马上看到效果就变了,欢迎大家一起讨论更好的,更精准的分页查询,电脑资料
《分页存储过程(二)在sqlserver中返回更加准确的分页结果》(https://www.unjs.com)。
上面的T-SQL只在SQL Server 2005上调试成功。
推荐一篇MS SQL Server的查询计划的相关内容,可以利用它优化SQL,写的不错。引用:SqlServer 执行计划及Sql查询优化初探
您可能感兴趣的文章:
深入sql server 2005 万能分页存储过程的详解
基于Sql Server通用分页存储过程的解决方法
SQL Server 2005通用分页存储过程及多表联接应用
针对SQL 2000 的分页存储过程代码分享
分页存储过程(三)在sqlserver中打造更加准确的分页结果
sqlserver 千万数量级分页存储过程代码
2分法分页存储过程脚本实例
QQ空间 搜狐微博 人人网 开心网 百度搜藏更多
Tags:分页 存储过程
复制链接收藏本文打印本文关闭本文返回首页
上一篇:SqlServer 执行计划及Sql查询优化初探
下一篇:SQL SERVER 2000通讯管道后复用劫持
相关文章
2010-09-09通过SQL语句直接把表导出为XML格式
2013-08-08SQLSERVER数据库备份后无法还原的解决办法
2013-04-04关于SQL Server查询语句的使用
2011-03-03SQL Server允许重复空字段不空字段值唯一
2012-02-02数据库中聚簇索引与非聚簇索引的区别[图文]
2013-02-02SQL Server利用bcp命令把SQL语句结果生成文本文件
2011-08-08SQL学习笔记六 union联合结果集使用
2009-10-10Excel导入Sqlserver数据库脚本
2009-11-11用户"sa"登陆失败 SQLServer 错误18456的解决方法
2009-06-06SqlServer 序号列的实现方法
文章评论
最 近 更 新
SQL语句实现删除ACCESS重复记录的两种方法
Sql2000数据库的备份文件恢复到Sql2005的
有用的SQL语句(删除重复记录,收缩日志)
sqlserver CONVERT()函数用法小结
获取数据库中两个时间字段的相差天数及AB
如何将sql执行的错误消息记录到本地文件中
SQLServer中字符串左对齐或右对齐显示的s
sql语句之数据操作介绍
MSSQL 生成日期列表代码
sql查询出各科成绩最好的学生信息
热 点 排 行
SQL Server 2008图文安装教程
SQL Server 2012 安装图解教程(附
sqlserver中distinct的用法(不重
SQL Server导入、导出、备份数据
SQL语句去掉重复记录,获取重复记
SQL Server数据库入门学习总结
SQL Server错误代码大全及解释(
sql convert函数使用小结
sql 时间函数 整理的比较全了
用SQL语句添加删除修改字段、一些