取SQL分组中的某几行数据
取SQL分组中的某几行数据
对表中数据分组,有时只需要某列的聚合值;有时却需要返回整行数据,常用的方法有:子查询、ROW_NUMBER、APPLY,总体感觉还是ROW_NUMBER比较直观。
测试数据:

if OBJECT_ID('testGroup') is not null
drop table testGroup
GO
create table testGroup
(
ID int identity primary key,
UserID int,
OrderID int
)
GO
insert testGroup
select 1,10 union all
select 1,20 union all
select 1,30 union all
select 2,100 union all
select 2,200 union all
select 3,1000 union all
select 3,2000 union all
select 3,3000 union all
select 3,4000

一. 取分组中第1行(最大/最小值)
1. 取出分组中某列最大/最小值,不要求显示其他列
最常见的分组聚合,用group by 分组时,只有参加分组/聚合的列才可以被显示。

select UserID, MAX(OrderID) as MaxOrderID
from testGroup
group by UserID

2. 取出分组中某列最大/最小值,要求显示其他列
要显示表中其他列,用group by 不好实现,可以借助子查询。

select * from testGroup a
where ID = (select MAX(ID) from testGroup b where a.UserID = b.UserID)
order by ID
--或者
select * from testGroup
where ID in (select MAX(ID) from testGroup group by UserID)
--或者
select * from testGroup as a
where a.ID in (select top 1 ID from testGroup b where a.UserID = b.UserID order by b.OrderID desc)
--或者
select * from testGroup a
where not exists(select 1 from testGroup b where a.UserID = b.UserID and a.OrderID < b.OrderID)
--或者
select * from testGroup a
where (select count(1) from testGroup b where a.UserID = b.UserID and a.id <= b.id) = 1

二. 取分组中前N行(排名前几名)
前N行为正向排序(ASC),后N行改为反向排序(DESC)即可,N=1时也就是取最大/最小值的行。下面以前2名(N=2)为例。
1. SQL Server 2000的写法
(1)子查询

select * from testGroup as a
where a.ID in (select top 2 ID from testGroup b where a.UserID = b.UserID order by b.OrderID)
--或者
select * from testGroup a
where not exists (select 1 from testGroup b where a.UserID = b.UserID and a.OrderID > b.OrderID
having count(1) >= 2)
--或者
select * from testGroup a
where (select count(1) from testGroup b where a.UserID = b.UserID and a.ID >= b.ID) <= 2
--没有唯一标识的表,可以用checksum来标识每行
select * from testGroup as a
where checksum(*) in (select top 2 checksum(*) from testGroup b where a.UserID = b.UserID order by b.OrderID)

2. SQL Server 2005新语法
(2) ROW_NUMBER()

select ID, UserID, OrderID
from
(select *, ROW_NUMBER() over(partition by UserID order by OrderID) num
from testGroup ) t
where t.num between 1 and 2

(3) APPLY(TOP)

select distinct t.* from testGroup a
cross apply (select top 2 ID, UserID, OrderID from testGroup b
where a.UserID = b.UserID order by b.OrderID) as t

三. 取分组中第N行(排名第N名)
把上面的查询中,范围值都改为固定值,就可以取具体某一行了,下面以第3名(N=3)为例。
(1) 子查询

select * from testGroup a
where (select count(1) from testGroup b where a.UserID = b.UserID and a.OrderID >= b.OrderID) = 3
--或者
select * from testGroup a
where exists (select 1 from testGroup b where a.UserID = b.UserID and a.OrderID >= b.OrderID
having count(1) = 3)

(2) ROW_NUMBER()

select ID, UserID, OrderID
from
(select *, ROW_NUMBER() over(partition by UserID order by OrderID) num
from testGroup ) t
where t.num = 3

取SQL分组中的某几行数据的更多相关文章
- 05. 取SQL分组中的某几行数据
对表中数据分组,有时只需要某列的聚合值:有时却需要返回整行数据,常用的方法有:子查询.ROW_NUMBER.APPLY,总体感觉还是ROW_NUMBER比较直观.测试数据: if OBJECT_ID( ...
- 取SQL分组中某几行数据
常用的方法有:子查询.ROW_NUMBER.APPLY,总体感觉还是ROW_NUMBER比较直观 if OBJECT_ID('testGroup') is not null drop table te ...
- sql-实现select取行号、分组后在分组内排序、每个分组中的前n条数据
表结构设计: 实现select取行号 sql局部变量的2种方式 set @name='cm3333f'; select @id:=1; 区别:set 可以用=号赋值,而select 不行,必须使用:= ...
- 在mysql中使用group by和order by取每个分组中日期最大一行数据
转载自:https://blog.csdn.net/shiyong1949/article/details/78482737 在mysql中使用group by进行分组后取某一列的最大值,我们可以直接 ...
- ORACLE 中rownum和row_number()的使用区别(可指定取sql结果集的第几个数据)
这篇文章主要介绍了oracle中rownum和row_number()的使用方法以及区别和联系,十分的详细,有需要的小伙伴可以参考下. row_number()over(partition by ...
- mysql先分组,然后取每个分组中的第2大的记录
文章参考http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/ 首先建表: ...
- 统计mysql库中每张表的行数据
修改数据库配置文件:vim /etc/my.cnf [client] user=username password=password 使用shell脚本统计表中的行数据:count.sh #!/bin ...
- 在csv表格中修改/追加某行数据
思路: 文本文件不能随意穿插信息,但是通过使用Seek()方法,可以在读取文本文件中移动光标从而修改所要修改的行. 思路步骤: 1.读取文件,打开csv文件,获取文件流,seek移动光标到开始, fo ...
- hive中同列多行数据组合的方法以及array to string要点(行转列)
1. 同列多行数据组合成一个字段cell的方法, top N 问题的hive方案 如下: hive 列转行 to json与to array list set等复杂结构,hive topN的提取的窗口 ...
随机推荐
- [CLR via C#]1.3 加载公共语言运行时
原文:[CLR via C#]1.3 加载公共语言运行时 1. 你生成的每个程序集可以是EXE,也可以是DLL.最终都是有CLR管理这些程序集中代码的执行. 2. VS2010中,创建新的EXE项目时 ...
- Net平台下的消息队列介绍
Net平台下的消息队列介绍 本系列主要记录最近学习消息队列的一些心得体会,打算形成一个系列文档.开篇主要介绍一下.Net平台下一些主流的消息队列框架. RabbitMQ:http:// ...
- java23种设计模式详解(转)
设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...
- pyqt学习总结
一.学习来由: 近期一段时间,应朋友的须要,完毕一款抓取软件.一般而言,python是我比較熟悉的语言,又有丰富的抓取和解析模块,所以果断选择之. 而这远远不是重点,后台程序在工作做常常写,所以比較熟 ...
- PHP 调用微信JS-SDK 开发详解 [网摘]
一:准备文件,并将文件置于网站根目录下 access_token.json {"access_token":"","expire_time" ...
- Caused by: java.lang.ClassNotFoundException: org.dom4j.DocumentException
1.错误描写叙述 信息: Initializing c3p0-0.9.2.1 [built 20-March-2013 10:47:27 +0000; debug? true; trace: 10] ...
- dom03
鼠标事件: 键盘事件: //通过class获取元素,封装一个通过class获取元素的方法 //IE10以下不支持document.getElementByClass() function getByC ...
- How to: Installshield做安装包时如何添加文件
原文:How to: Installshield做安装包时如何添加文件 我一直以为这不是一个问题,可是没想到在几个群内,对于如何向安装包添加文件不解的大有人在,今日稍暇,整理成篇,以供参考 首先我想再 ...
- SQL点滴27—性能分析之执行计划
原文:SQL点滴27-性能分析之执行计划 一直想找一些关于SQL语句性能调试的权威参考,但是有参考未必就能够做好调试的工作.我深信实践中得到的经验是最珍贵的,书本知识只是一个引导.本篇来源于<I ...
- 清掉kugo 7 和千千静听的广告
as below,we know Ad is bothering Way to solve it! Original URL :http://tieba.baidu.com/p/1240429497? ...