蝈蝈俊.net

-- 用随笔来记录自己的技术感触
随笔 - 673, 评论 - 4328, 引用 - 276

导航

关于

记录自己的技术心得

标签

每月存档

最新留言

  • Iwdwzwrb
    Very funny pictures <a href=" http://www.wikio.com/user/tujebisao/bio "&...
    by Iwdwzwrb(匿名) on 2010/3/19 18:21:12
  • Eebvfxax
    Very Good Site <a href=" http://www.wikio.com/user/isufaifameu/bio "&gt...
    by Eebvfxax(匿名) on 2010/3/19 17:46:52
  • Bbymerhc
    Very interesting tale <a href=" http://www.wikio.com/user/isufaifameu/bio "...
    by Bbymerhc(匿名) on 2010/3/19 16:51:18
  • Fhpjpshb
    Very funny pictures <a href=" http://www.wikio.com/user/hupofugomia/bio "&a...
    by Fhpjpshb(匿名) on 2010/3/19 16:16:20
  • Wgugqqku
    Very Good Site <a href=" http://www.wikio.com/user/hupofugomia/bio "&gt...
    by Wgugqqku(匿名) on 2010/3/19 15:22:56
  • Mtrpkxnr
    <a href=" http://www.wikio.com/user/lyepylatytof/bio ">sex free lol...
    by Mtrpkxnr(匿名) on 2010/3/19 14:47:56
  • Kshngzfl
    It's funny goodluck <a href=" http://www.wikio.com/user/lyepylatytof/bio "&...
    by Kshngzfl(匿名) on 2010/3/19 13:51:32
  • Whaxznox
    this post is fantastic <a href=" http://www.wikio.com/user/biukyera/bio "&a...
    by Whaxznox(匿名) on 2010/3/19 13:16:55
  • Bhtmssbu
    Excellent work, Nice Design <a href=" http://www.wikio.com/user/biukyera/bio &qu...
    by Bhtmssbu(匿名) on 2010/3/19 12:21:10
  • Qznunxlt
    I love this site <a href=" http://www.wikio.com/user/sonomureper/bio "&...
    by Qznunxlt(匿名) on 2010/3/19 11:47:59

广告

 

分类统计时候,我们可能经常会碰到这样的需求,每个分类按照一定顺序,取几条数据,然后在一起显示。

这个问题的解决方法,我们通过搜索引擎,可以找到很多中。但是不是SQL语句过于复杂,就是在数据量比较大时候,性能特别成问题。

今天我就碰到这样一个需求。而我自己的解决方案就是SQL过于复杂,或者性能比较差的。为此我在CSDN论坛发了个帖子,看有没有更好的解决方案。

http://topic.csdn.net/u/20080504/14/5c5866c3-8b91-45ef-ab17-f994f88f8e42.html

CSDN的 SQL Server 板块  不愧是高手云集,问题发出不到半小时,就获得了近10种解决方案。经过测试,我把性能最高,且SQL不复杂的方案整理出来。特别感谢 jinjazz 的解答。

 

问题详细描述如下:

比如,假设我们有下面这样结构的一张表,这张表的数据量非常巨大。

CREATE TABLE table1
(
[ID] [bigint] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](128) NOT NULL,
[class] int not null,
[date] datetime not null
)

class 表示分类编号。 分类数不固定, 至少有上千种分类
date 表示该条记录被更新的时间
我们现在想获得每个分类最新被更新的5条记录。

 

解决方案

select id,name,class,date from(
select id,name,class,date ,row_number() over(partition by class order by date desc)
as rowindex from table1) a
where rowindex <= 5

 

解决方案简单说明:

这个解决方案的关键就是使用了SQL 2005 的 ROW_NUMBER 这个全新的函数。

ROW_NUMBER ( ) 函数的语法如下:
ROW_NUMBER ( )     OVER ( [ <partition_by_clause> ] <order_by_clause> )

OVER 子句中的 PARTITION BY 将结果集分为多个分区。
OVER 子句中的 ORDER BY 将对 ROW_NUMBER 进行排序。

下面是MSDN的几个简单例子:

 

以下示例将根据年初至今的销售额,返回 AdventureWorks 中销售人员的 ROW_NUMBER。

USE AdventureWorks; 
GO

SELECT c.FirstName, c.LastName ,
ROW_NUMBER() OVER(ORDER BY SalesYTD DESC) AS 'Row Number' ,s.SalesYTD, a.PostalCode

FROM Sales.SalesPerson s INNER JOIN Person.Contact c ON s.SalesPersonID = c.ContactID
INNER JOIN Person.Address a ON a.AddressID = c.ContactID
WHERE TerritoryID IS NOT NULL AND SalesYTD <> 0;


以下示例将返回行号为 50 到 60 的行(包含这两行),并按 OrderDate 进行排序。

USE AdventureWorks; 
GO

WITH OrderedOrders AS ( SELECT SalesOrderID, OrderDate,
ROW_NUMBER() OVER (ORDER BY OrderDate) AS 'RowNumber'
FROM Sales.SalesOrderHeader )

SELECT * FROM OrderedOrders WHERE RowNumber BETWEEN 50 AND 60;


 

以下示例说明了如何使用 PARTITION BY 参数。

USE AdventureWorks; 
GO

SELECT c.FirstName, c.LastName ,
ROW_NUMBER() OVER (PARTITION BY PostalCode ORDER BY SalesYTD DESC) AS 'Row Number' ,
s.SalesYTD, a.PostalCode

FROM Sales.SalesPerson s INNER JOIN Person.Contact c ON s.SalesPersonID = c.ContactID
INNER JOIN Person.Address a ON a.AddressID = c.ContactID
WHERE TerritoryID IS NOT NULL AND SalesYTD <> 0;

打印 | 张贴于 2008-05-04 15:31:47 | Tag:数据库开发管理心得

留言反馈

#re: 每个分类取最新的几条的SQL实现 编辑
sql2005的特性之一,在08年过半时才拿出来也能算上最佳文章?
2008-05-06 10:21:17 | [匿名:fhmsha]

发表留言

标题
姓名
邮件
主页
留言 

Powered by: Joycode.MVC引擎 0.5.2.0