SQL Server:获得用户最新或前n条订单的几种SQL语句

本文介绍了在SQL Server中查询每个用户的最新订单信息的方法。通过创建索引并使用不同SQL查询技巧,包括子查询、JOIN操作及窗口函数等,对比了四种方法的效率差异。

  场景:有一张用户表,一个订单表,要求获得一个用户对应的最新的一条订单信息。

     实现以上要求,我们可以用以下几种方式,但是效率却相差很远。

     首先我们在Order表中,创建一个索引:

CREATE   UNIQUE   INDEX  idx_eid_odD_oidD  ON  Orders(EmployeeID,OrderDate  DESC ,OrderID  DESC )

  多个OrderId是为了在OrderData相同的情况下,按订单号倒序,是个辅助属性。

     方法1:  

SELECT  EmployeeID,OrderID  FROM  Orders  AS  O1
WHERE  OrderID  =  (
    
SELECT   TOP ( 1 )OrderID  FROM  Orders  AS  O2
    
WHERE  O1.EmployeeID  =  O2.EmployeeID
    
ORDER   BY  OrderDate  DESC  ,OrderID  DESC
)

     如果想获得前n条订单信息,把 = 号改成IN,然后TOP(n)就可以了。

     不论是取一条还是多条,即使有索引,数据多的情况下,也是最慢的。

     方法2:

SELECT  O.EmployeeID,O.OrderID  FROM  (
    
SELECT  EmployeeID,( SELECT   TOP ( 1 )OrderID  FROM  Orders  AS  O2  WHERE  E.EmployeeID  =  O2.EmployeeID  ORDER   BY  OrderDate  DESC ,OrderID  DESC AS  OrderID 
    
FROM  Employees  AS  E
AS  EO 
INNER   JOIN  Orders  AS  O
ON  EO.OrderID  =  O.OrderID

     方法2只能取一条信息,不能取多条信息。

     在取一条的情况下,这个要比方法1快多了,因为用户相比订单信息要少很多。

     方法3:

SELECT  E.EmployeeID,O.OrderID  FROM  Employees  AS  E
CROSS  APPLY (
    
SELECT   TOP ( 1 ) *   FROM  Orders  AS  O1  WHERE  E.EmployeeID  =  O1.EmployeeID  ORDER   BY  O1.OrderDate  DESC ,O1.OrderID  DESC
AS  O

     这个应用到了SQL Server 2005或更高版本的一些新特性,这个效率要比方法2还好。

     如果想取得多条,只需更改TOP(n)即可。

     APPLY详解,参见 http://www.cnblogs.com/xbf321/archive/2011/08/14/apply-in-sql-server.html

     方法4:

SELECT  O1.EmployeeID,O1.OrderID 
FROM  Orders O1  JOIN  (
    
SELECT  ROW_NUMBER()  OVER (PARTITION  BY  EmployeeID  ORDER   BY  OrderDate  DESC ,OrderID  DESC AS  RowNumber, *  
    
FROM  Orders  AS  OT
AS  O2
ON  O1.OrderID  =  O2.OrderID
WHERE  O2.RowNumber  =   1

     这个ROW_NUMBER函数也是在SQL Server 2005后新增的,使用这个和方法3查不多,甚至比3更好,但要注意一点是先按EmployeeID分区,然后再排序。

 

     结合以上方法, 建议用方法3。

 

 

转载于:https://www.cnblogs.com/xbf321/archive/2011/08/15/top-one-or-top-n-in-sql-server.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值