分类统计时候,我们可能经常会碰到这样的需求,每个分类按照一定顺序,取几条数据,然后在一起显示。
这个问题的解决方法,我们通过搜索引擎,可以找到很多中。但是不是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;
转自:http://blog.joycode.com/ghj/archive/2008/05/04/115104.aspx
分享到:
相关推荐
SQL实现每个分类取最新的几条记录 在实际应用中,经常需要从数据库中获取每个分类最新的几条记录,例如,获取每个分类最新的5条记录。在本文中,我们将介绍使用SQL语句来实现该需求的解决方案。 创建表 首先,...
### 单条SQL语句实现复杂逻辑几例 在数据库管理与开发中,有时需要处理较为复杂的业务逻辑,而这些逻辑往往可以通过一条精心构造的SQL语句来完成。本文将介绍一个具体的例子,即如何使用单条SQL语句来生成指定商品...
–按某一字段分组取最大(小)值所在行的数据 代码如下: /* 数据如下: nameval memo a 2 a2(a的第二个值) a 1 a1–a的第一个值 a 3 a3:a的第三个值 b 1 b1–b的第一个值 b 3 b3:b的第三个值 b 2 b2b2b2b2 b 4 b4b4 b ...
- **最近数据查询:** 如果需要获取最新的几条记录(如最近发布的文章),可以通过这种方法结合降序排序来实现。 - **性能优化:** 当只需要获取最新的一小部分数据时,这种方法能够减少不必要的数据处理。 **注意...
在SQL查询中,从每个分类选择10条记录是一个常见的需求,这通常涉及到数据库的数据分组和限制。在这个场景下,我们看到的SQL语句是用于实现这一目标的一个实例。让我们详细探讨一下这个语句的工作原理及其背后的逻辑...
2. **唯一性**:对于主键字段,如`id`,每个值必须是唯一的,不能有重复。 3. **引用完整性**:如果涉及到外键,插入的值必须是其他表中存在的有效记录。 4. **事务处理**:在批量插入时,使用事务可以保证数据的...
在这个实现过程中,有几个重要的技术点需要注意: - **`ROW_NUMBER()`函数**:这个函数在窗口函数家族中非常重要,它可以为每一行分配一个唯一的行号,这对于后续的操作非常关键。 - **使用子查询**:在最后一步中...
2019年1月的“2019年最新淘宝叶子类目分类ID-24043条”数据集提供了最新的淘宝类目分类信息,总计24043条记录,这些数据以SQL格式存储,可以直接导入到数据库中进行分析和使用。 首先,我们要理解什么是淘宝类目ID...
1. 首先,对`TestData`表按`Data`字段分组,找出每个组的最小`ID`: ```sql SELECT MIN(ID) FROM TestData GROUP BY Data ``` 2. 然后,使用`IN`操作符将这些最小ID包含在查询中,以获取对应的完整行: ```sql ...
同样需要一个主键(如身份证号)来唯一标识每个读者。 3. **借阅记录表**:记录每本书的借阅情况,包括借书人ID、图书ID、借阅日期、预计归还日期和实际归还日期。这将用于追踪图书的流通状态和逾期情况。 4. **...
目标是使用SQL语句计算出每个源ID (`ܺķ`) 在不同时期的累计预计值 (`ۼԤ`),即从最早的时间点开始到当前时间点的所有预计值之和。 #### 2.2 SQL实现 接下来,我们将展示具体的SQL查询语句,以实现上述目标: ``...
打个比方你要查询每月排名前十的那些记录,或者每月销售前十的车辆。
在函数体中,我们使用了一个 WHILE 循环来遍历表中的记录,并将每个记录的 `收费类别` 字段值追加到 `@str` 变量中。最后,我们使用 `RIGHT` 函数来删除最后一个逗号,并返回最终结果。 知识点 2:使用 CROSS APPLY...
传说用这个语句管用:select top 5 * from tablename order by newid() 我放到sql的查询分析器里去执行果然管用,随机抽取5条信息,不停的换,结果我应用到程序里的时候就不管用了,总是那几条,于是对这个东西进行...
此方法利用了数据表中的`ID`字段,通过设定一个起始点(通常是上一页的最大`ID`值),然后选取满足条件的前几条记录作为当前页的数据。这种方法同样适用于主键为标识列的情况。 **具体实现** 以下示例展示了如何...
这里先通过子查询找到每个用户名称下的最大 `user_id`,然后在外层删除除了最大 `user_id` 对应的记录之外的所有重复记录。这种方式可以有效地去除重复记录,但需要注意的是,它保留了每个用户名称下的最大 `user_id...
这个查询会计算每个SQL语句的执行次数和总执行时间,然后按执行次数降序排序,并取前20%的结果。 通过分析这两个脚本,我们可以学习到以下几点关于SQL优化的知识: 1. **性能监控**:了解SQL语句的执行情况是优化...
- 接下来的几条记录分别代表了北京市内的海淀区、朝阳区、顺义区等地区的信息。 #### 综合分析 1. **应用场景**:这份数据可以应用于各种需要处理地理位置信息的场景,如地图应用、物流配送系统、天气预报服务等。...
这种方法利用了ID的递增特性,通过找到前一页最后一个ID的值,然后选择大于该值的所有记录中的前几条。实现方式如下: ```sql SELECT TOP 10 * FROM TestTable WHERE (ID > (SELECT MAX(id) FROM (SELECT TOP 20 ...