plantegg 发表于 2015-6-29 18:16:56

分页存储过程(四)在MS SQL Server中打造更加准确,且有一点效率提升的的分页结果

  在上一篇分页存储过程(三)在MS SQL Server中打造更加准确的分页结果
  中,我虽然抛弃了大家不喜欢的游标,但是临时表还是存在的,但是ascrat老兄的意思被我误解了一半,所以,哈哈。。。。。。。下面是老兄在上一篇的回复,我又重新修改了T-SQL,这回要比上回的更好。
  感谢老兄的指点,希望大家贡献更好的,感谢大家的参与!!!
  
  
  
#2楼 ascrat      2010-05-23 23:51
  呃...可能楼主误解了我的意思..我说的是这样..
1, 主表的查询还是你写的方式
2, 明细的像这样:
select .... from
(
select 主表的10个定单, 需要的主表字段 from 主表..分页..
) a
inner join 明细表 b on a.主表ID = b.主表ID
你可以想象一下..如果这里的集合 a 不只是一个主表筛选出来, 而是从很多个表连接并计算得出的集合, 如果每个集合都 into 到临时表里去, 效率暂且不说..代码也会多很多的.
  
    
  

代码


--ascrat老兄的提示,好办法啊
--省去了游标,省去了临时表
--(学习的)路漫漫其修远啊

SELECT a.*,od.* FROM (
SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY oi.CreateDate DESC) AS rownumber,oi.OrderSeqNO
                FROM OrderInfo oi WHERE oi.OrderSeqNO LIKE '%2%' ) AS o
WHERE o.rownumber BETWEEN 10 AND 20
) a
INNER JOIN OrderDetail od ON a.OrderSeqNO=od.OrderSeqNO  
  
  这个系列的完整代码如下
  

代码

--SELECT TOP 10 oi.OrderSeqNO, oi.GoodsName ,ci.CompanyName,od.*
--FROM OrderInfo oi INNER JOIN CompanyInfo ci ON oi.CompanyID=ci.CompanyID
--LEFT JOIN OrderDetail od ON oi.OrderSeqNO=od.OrderSeqNO


--使用row_unmber()实现分页
--本来我们想要的结果是10条订单,结果却不是10条订单,而是10条明细
--其实是针对的子表进行分页了,订单并不是要显示的个数,出来的个数是明细的个数
--就是因为主表和子表联合查询的结果,主表记录和子表记录是1:N的关系,一个主表记录有多个明细

--建立聚集索引
-- CLUSTERED INDEX INDEX_OrderInfoON OrderInfo(OrderSeqNo)
--显示查询执行计划
SET STATISTICS IO ON

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

--不用游标的分页
--先将分页的主表放在临时表中,然后用临时表和子表联合查询,来获取子表信息
--既保证了分页的正确性,也包括了子表信息
CREATE TABLE #order
(
    number BIGINT,
    orderseqno VARCHAR(36),   
)
insert into #order
SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY oi.CreateDate DESC) AS rownumber,oi.OrderSeqNO
                FROM OrderInfo oi WHERE oi.OrderSeqNO LIKE '%2%' ) AS o
WHERE o.rownumber BETWEEN 10 AND 20

SELECT * FROM #order INNER JOIN OrderDetail od ON od.OrderSeqNO=#order.orderseqno

DROP TABLE #order


--ascrat老兄的提示,好办法啊
--省去了游标,省去了临时表
--(学习的)路漫漫其修远啊

SELECT a.*,od.* FROM (
SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY oi.CreateDate DESC) AS rownumber,oi.OrderSeqNO
                FROM OrderInfo oi WHERE oi.OrderSeqNO LIKE '%2%' ) AS o
WHERE o.rownumber BETWEEN 10 AND 20
) a
INNER JOIN OrderDetail od ON a.OrderSeqNO=od.OrderSeqNO


--解决上面的问题,有以下几种办法
--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
页: [1]
查看完整版本: 分页存储过程(四)在MS SQL Server中打造更加准确,且有一点效率提升的的分页结果