按某一字段分组取最大(小)值所在行的数据(为MVP准备的文章)

时间:2021-09-29 15:12:47
--按某一字段分组取最大(小)值所在行的数据
(爱新觉罗.毓华 2007-10-23于浙江杭州)
/*
数据如下:
name val 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    5   b5b5b5b5b5
*/
--创建表并插入数据:
create table tb(name varchar(10),val int,memo varchar(20))
insert into tb values('a',    2,   'a2(a的第二个值)')
insert into tb values('a',    1,   'a1--a的第一个值')
insert into tb values('a',    3,   'a3:a的第三个值')
insert into tb values('b',    1,   'b1--b的第一个值')
insert into tb values('b',    3,   'b3:b的第三个值')
insert into tb values('b',    2,   'b2b2b2b2')
insert into tb values('b',    4,   'b4b4')
insert into tb values('b',    5,   'b5b5b5b5b5')
go

--一、按name分组取val最大的值所在行的数据。
--方法1:
select a.* from tb a where val = (select max(val) from tb where name = a.name) order by a.name
--方法2:
select a.* from tb a where not exists(select 1 from tb where name = a.name and val > a.val)
--方法3:
select a.* from tb a,(select name,max(val) val from tb group by name) b where a.name = b.name and a.val = b.val order by a.name
--方法4:
select a.* from tb a inner join (select name , max(val) val from tb group by name) b on a.name = b.name and a.val = b.val order by a.name
--方法5
select a.* from tb a where 1 > (select count(*) from tb where name = a.name and val > a.val ) order by a.name
/*
name       val         memo                 
---------- ----------- -------------------- 
a          3           a3:a的第三个值
b          5           b5b5b5b5b5
*/

--二、按name分组取val最小的值所在行的数据。
--方法1:
select a.* from tb a where val = (select min(val) from tb where name = a.name) order by a.name
--方法2:
select a.* from tb a where not exists(select 1 from tb where name = a.name and val < a.val)
--方法3:
select a.* from tb a,(select name,min(val) val from tb group by name) b where a.name = b.name and a.val = b.val order by a.name
--方法4:
select a.* from tb a inner join (select name , min(val) val from tb group by name) b on a.name = b.name and a.val = b.val order by a.name
--方法5
select a.* from tb a where 1 > (select count(*) from tb where name = a.name and val < a.val) order by a.name
/*
name       val         memo                 
---------- ----------- -------------------- 
a          1           a1--a的第一个值
b          1           b1--b的第一个值
*/

--三、按name分组取第一次出现的行所在的数据。
select a.* from tb a where val = (select top 1 val from tb where name = a.name) order by a.name
/*
name       val         memo                 
---------- ----------- -------------------- 
a          2           a2(a的第二个值)
b          1           b1--b的第一个值
*/

--四、按name分组随机取一条数据。
select a.* from tb a where val = (select top 1 val from tb where name = a.name order by newid()) order by a.name
/*
name       val         memo                 
---------- ----------- -------------------- 
a          1           a1--a的第一个值
b          5           b5b5b5b5b5
*/

--五、按name分组取最小的两个(N个)val
select a.* from tb a where 2 > (select count(*) from tb where name = a.name and val < a.val ) order by a.name,a.val
select a.* from tb a where val in (select top 2 val from tb where name=a.name order by val) order by a.name,a.val
select a.* from tb a where exists (select count(*) from tb where name = a.name and val < a.val having Count(*) < 2) order by a.name
/*
name       val         memo                 
---------- ----------- -------------------- 
a          1           a1--a的第一个值
a          2           a2(a的第二个值)
b          1           b1--b的第一个值
b          2           b2b2b2b2
*/

--六、按name分组取最大的两个(N个)val
select a.* from tb a where 2 > (select count(*) from tb where name = a.name and val > a.val ) order by a.name,a.val
select a.* from tb a where val in (select top 2 val from tb where name=a.name order by val desc) order by a.name,a.val
select a.* from tb a where exists (select count(*) from tb where name = a.name and val > a.val having Count(*) < 2) order by a.name
/*
name       val         memo                 
---------- ----------- -------------------- 
a          2           a2(a的第二个值)
a          3           a3:a的第三个值
b          4           b4b4
b          5           b5b5b5b5b5
*/
--七,如果整行数据有重复,所有的列都相同。
/*
数据如下:
name val memo
a    2   a2(a的第二个值)
a    1   a1--a的第一个值
a    1   a1--a的第一个值
a    3   a3:a的第三个值
a    3   a3:a的第三个值
b    1   b1--b的第一个值
b    3   b3:b的第三个值
b    2   b2b2b2b2
b    4   b4b4
b    5   b5b5b5b5b5
*/
--在sql server 2000中只能用一个临时表来解决,生成一个自增列,先对val取最大或最小,然后再通过自增列来取数据。
--创建表并插入数据:
create table tb(name varchar(10),val int,memo varchar(20))
insert into tb values('a',    2,   'a2(a的第二个值)')
insert into tb values('a',    1,   'a1--a的第一个值')
insert into tb values('a',    1,   'a1--a的第一个值')
insert into tb values('a',    3,   'a3:a的第三个值')
insert into tb values('a',    3,   'a3:a的第三个值')
insert into tb values('b',    1,   'b1--b的第一个值')
insert into tb values('b',    3,   'b3:b的第三个值')
insert into tb values('b',    2,   'b2b2b2b2')
insert into tb values('b',    4,   'b4b4')
insert into tb values('b',    5,   'b5b5b5b5b5')
go

select * , px = identity(int,1,1) into tmp from tb

select m.name,m.val,m.memo from
(
  select t.* from tmp t where val = (select min(val) from tmp where name = t.name)
) m where px = (select min(px) from
(
  select t.* from tmp t where val = (select min(val) from tmp where name = t.name)
) n where n.name = m.name)

drop table tb,tmp

/*
name       val         memo
---------- ----------- --------------------
a          1           a1--a的第一个值
b          1           b1--b的第一个值

(2 行受影响)
*/
--在sql server 2005中可以使用row_number函数,不需要使用临时表。
--创建表并插入数据:
create table tb(name varchar(10),val int,memo varchar(20))
insert into tb values('a',    2,   'a2(a的第二个值)')
insert into tb values('a',    1,   'a1--a的第一个值')
insert into tb values('a',    1,   'a1--a的第一个值')
insert into tb values('a',    3,   'a3:a的第三个值')
insert into tb values('a',    3,   'a3:a的第三个值')
insert into tb values('b',    1,   'b1--b的第一个值')
insert into tb values('b',    3,   'b3:b的第三个值')
insert into tb values('b',    2,   'b2b2b2b2')
insert into tb values('b',    4,   'b4b4')
insert into tb values('b',    5,   'b5b5b5b5b5')
go

select m.name,m.val,m.memo from
(
  select * , px = row_number() over(order by name , val) from tb
) m where px = (select min(px) from
(
  select * , px = row_number() over(order by name , val) from tb
) n where n.name = m.name)

drop table tb

/*
name       val         memo
---------- ----------- --------------------
a          1           a1--a的第一个值
b          1           b1--b的第一个值

(2 行受影响)
*/

60 个解决方案

#1


SF

#2


抢沙发

#3


SF

#4


引用 2 楼 Limpire 的回复:
抢沙发

#5


引用 4 楼 Limpire 的回复:
引用 2 楼 Limpire 的回复:
抢沙发

#6


还是沙发?

#7


引用 5 楼 Limpire 的回复:
引用 4 楼 Limpire 的回复:
引用 2 楼 Limpire 的回复:
抢沙发

#8


引用 7 楼 Limpire 的回复:
引用 5 楼 Limpire 的回复:
引用 4 楼 Limpire 的回复:
引用 2 楼 Limpire 的回复:
抢沙发

#9


引用 6 楼 happyflystone 的回复:
还是沙发?

#10


BD

#11


up

#12


引用 11 楼 kelph 的回复:
up

#13


up

#14


这些应该顶为2007年度的精华贴

#15


UP

接分啊

#16


UP 

接分啊

#17


引用 8 楼 Limpire 的回复:
引用 7 楼 Limpire 的回复:
引用 5 楼 Limpire 的回复: 
引用 4 楼 Limpire 的回复: 
引用 2 楼 Limpire 的回复: 
抢沙发 

#18


引用 16 楼 GDC_ZhaoYZ0304360 的回复:
UP  

接分啊

#19


引用 13 楼 kelph 的回复:
up

#20


up

#21


up up

#22


枪。。

#23




按某一字段分组取最大(小)值所在行的数据(为MVP准备的文章)


    [align=center] = = = =     = = = =
[/align]
 

#24




按某一字段分组取最大(小)值所在行的数据(为MVP准备的文章)按某一字段分组取最大(小)值所在行的数据(为MVP准备的文章)


    [align=center] = = = =     = = = =
[/align]
 

#25


引用 1 楼 happyflystone 的回复:
SF

#26


英雄的帖子就是这样给水掉的

#27


引用 17 楼 GDC_ZhaoYZ0304360 的回复:
引用 8 楼 Limpire 的回复:
引用 7 楼 Limpire 的回复: 
引用 5 楼 Limpire 的回复:  
引用 4 楼 Limpire 的回复:  
引用 2 楼 Limpire 的回复:  
抢沙发  

#28


引用 27 楼 GDC_ZhaoYZ0304360 的回复:
引用 17 楼 GDC_ZhaoYZ0304360 的回复:
引用 8 楼 Limpire 的回复: 
引用 7 楼 Limpire 的回复:  
引用 5 楼 Limpire 的回复:   
引用 4 楼 Limpire 的回复:   
引用 2 楼 Limpire 的回复:   
抢沙发   

#29


引用 28 楼 GDC_ZhaoYZ0304360 的回复:
引用 27 楼 GDC_ZhaoYZ0304360 的回复:
引用 17 楼 GDC_ZhaoYZ0304360 的回复: 
引用 8 楼 Limpire 的回复:  
引用 7 楼 Limpire 的回复:   
引用 5 楼 Limpire 的回复:    
引用 4 楼 Limpire 的回复:    
引用 2 楼 Limpire 的回复:    
抢沙发    

#30


Up,学习了!

#31


学习

#32


劫个色...

#33


打个劫

#34


good

#35


按某一字段分组取最大(小)值所在行的数据(为MVP准备的文章)

#36


牛人

#37


顶肺,速度结帖龟

#38


引用 37 楼 wzy_love_sly 的回复:
顶肺,速度结帖龟

#39


引用 37 楼 wzy_love_sly 的回复:
顶肺,速度结帖龟

#40


引用 39 楼 wzy_love_sly 的回复:
引用 37 楼 wzy_love_sly 的回复:
顶肺,速度结帖龟

#41


该回复于2008-05-13 18:01:50被版主删除

#42


支持 收藏先

#43


开发;卓越呼叫中心、三农热线”语音农业综合信息服务平台、卓越办公自动化软件、卓越电厂MIS系统、卓越客户关系管理系统、卓越网站制作、卓越医疗信息管理系统;沈阳卓越科技有限公司;www.excellence-tech.com

#44


写的不错嘛

#45


 温故而知新.接分

#46


***************************************************************************

思想决定行动,行动决定习惯,习惯决定命运.
程序员在深圳QQ群,交流产生思想碰撞.

部份专业群:
程序员在深圳c++群15195967
程序员在深圳英语学习群:23864353
程序员在深圳c++Ⅱ17409451
程序员在深圳嵌入式开发群37489763
程序员在深圳移动开发群31501597
程序员在深圳创业群33653422

部份高级程序员群:
高级群I:17538442
高级群II:7120862

部份初、中级程序员群:
第三群:2650485
第五群:29537639
第四群:28702746
第六群:10590618
第七群:10543585
第八群:12006492
第九群:19063074
第十群:2883885
第十一群:25460595
第十二群:9663807

深圳程序员QQ群联盟成立三年多,拥有三十个以上的QQ群,人数超二千多人,大量经验丰富的老手,成员从业于大公司(如微软、IBM,SUN,华为)、来自国内著名高校和研究院成员,和有丰富实践经验的高级程序员、系统分析员(包括参加过上亿元的项目的架构师),有很热爱技术的成员(包括自己写操作系统),还有少数女程序员。推荐:深程高级群I:17538442 深程高级群II:7120862 (深程高级群不欢迎新手,如果在深圳,月薪6K以下的别加入) c++:15195967  mobile:31501597嵌入式:37489763  
—————————————————————————————————————————— 
群内交流解决问题的方法,一般难以直接得到答案,问题的解决还是要靠自己。(授之以渔与授之以鱼的关系)。
*****************************************************************************

#47



UP

#48


up,抢沙发

#49


好例程,学习学习!!!

#50


学习!

#1


SF

#2


抢沙发

#3


SF

#4


引用 2 楼 Limpire 的回复:
抢沙发

#5


引用 4 楼 Limpire 的回复:
引用 2 楼 Limpire 的回复:
抢沙发

#6


还是沙发?

#7


引用 5 楼 Limpire 的回复:
引用 4 楼 Limpire 的回复:
引用 2 楼 Limpire 的回复:
抢沙发

#8


引用 7 楼 Limpire 的回复:
引用 5 楼 Limpire 的回复:
引用 4 楼 Limpire 的回复:
引用 2 楼 Limpire 的回复:
抢沙发

#9


引用 6 楼 happyflystone 的回复:
还是沙发?

#10


BD

#11


up

#12


引用 11 楼 kelph 的回复:
up

#13


up

#14


这些应该顶为2007年度的精华贴

#15


UP

接分啊

#16


UP 

接分啊

#17


引用 8 楼 Limpire 的回复:
引用 7 楼 Limpire 的回复:
引用 5 楼 Limpire 的回复: 
引用 4 楼 Limpire 的回复: 
引用 2 楼 Limpire 的回复: 
抢沙发 

#18


引用 16 楼 GDC_ZhaoYZ0304360 的回复:
UP  

接分啊

#19


引用 13 楼 kelph 的回复:
up

#20


up

#21


up up

#22


枪。。

#23




按某一字段分组取最大(小)值所在行的数据(为MVP准备的文章)


    [align=center] = = = =     = = = =
[/align]
 

#24




按某一字段分组取最大(小)值所在行的数据(为MVP准备的文章)按某一字段分组取最大(小)值所在行的数据(为MVP准备的文章)


    [align=center] = = = =     = = = =
[/align]
 

#25


引用 1 楼 happyflystone 的回复:
SF

#26


英雄的帖子就是这样给水掉的

#27


引用 17 楼 GDC_ZhaoYZ0304360 的回复:
引用 8 楼 Limpire 的回复:
引用 7 楼 Limpire 的回复: 
引用 5 楼 Limpire 的回复:  
引用 4 楼 Limpire 的回复:  
引用 2 楼 Limpire 的回复:  
抢沙发  

#28


引用 27 楼 GDC_ZhaoYZ0304360 的回复:
引用 17 楼 GDC_ZhaoYZ0304360 的回复:
引用 8 楼 Limpire 的回复: 
引用 7 楼 Limpire 的回复:  
引用 5 楼 Limpire 的回复:   
引用 4 楼 Limpire 的回复:   
引用 2 楼 Limpire 的回复:   
抢沙发   

#29


引用 28 楼 GDC_ZhaoYZ0304360 的回复:
引用 27 楼 GDC_ZhaoYZ0304360 的回复:
引用 17 楼 GDC_ZhaoYZ0304360 的回复: 
引用 8 楼 Limpire 的回复:  
引用 7 楼 Limpire 的回复:   
引用 5 楼 Limpire 的回复:    
引用 4 楼 Limpire 的回复:    
引用 2 楼 Limpire 的回复:    
抢沙发    

#30


Up,学习了!

#31


学习

#32


劫个色...

#33


打个劫

#34


good

#35


按某一字段分组取最大(小)值所在行的数据(为MVP准备的文章)

#36


牛人

#37


顶肺,速度结帖龟

#38


引用 37 楼 wzy_love_sly 的回复:
顶肺,速度结帖龟

#39


引用 37 楼 wzy_love_sly 的回复:
顶肺,速度结帖龟

#40


引用 39 楼 wzy_love_sly 的回复:
引用 37 楼 wzy_love_sly 的回复:
顶肺,速度结帖龟

#41


该回复于2008-05-13 18:01:50被版主删除

#42


支持 收藏先

#43


开发;卓越呼叫中心、三农热线”语音农业综合信息服务平台、卓越办公自动化软件、卓越电厂MIS系统、卓越客户关系管理系统、卓越网站制作、卓越医疗信息管理系统;沈阳卓越科技有限公司;www.excellence-tech.com

#44


写的不错嘛

#45


 温故而知新.接分

#46


***************************************************************************

思想决定行动,行动决定习惯,习惯决定命运.
程序员在深圳QQ群,交流产生思想碰撞.

部份专业群:
程序员在深圳c++群15195967
程序员在深圳英语学习群:23864353
程序员在深圳c++Ⅱ17409451
程序员在深圳嵌入式开发群37489763
程序员在深圳移动开发群31501597
程序员在深圳创业群33653422

部份高级程序员群:
高级群I:17538442
高级群II:7120862

部份初、中级程序员群:
第三群:2650485
第五群:29537639
第四群:28702746
第六群:10590618
第七群:10543585
第八群:12006492
第九群:19063074
第十群:2883885
第十一群:25460595
第十二群:9663807

深圳程序员QQ群联盟成立三年多,拥有三十个以上的QQ群,人数超二千多人,大量经验丰富的老手,成员从业于大公司(如微软、IBM,SUN,华为)、来自国内著名高校和研究院成员,和有丰富实践经验的高级程序员、系统分析员(包括参加过上亿元的项目的架构师),有很热爱技术的成员(包括自己写操作系统),还有少数女程序员。推荐:深程高级群I:17538442 深程高级群II:7120862 (深程高级群不欢迎新手,如果在深圳,月薪6K以下的别加入) c++:15195967  mobile:31501597嵌入式:37489763  
—————————————————————————————————————————— 
群内交流解决问题的方法,一般难以直接得到答案,问题的解决还是要靠自己。(授之以渔与授之以鱼的关系)。
*****************************************************************************

#47



UP

#48


up,抢沙发

#49


好例程,学习学习!!!

#50


学习!