`

分组后取最大值(mysql)

    博客分类:
  • SQL
阅读更多
--
按某一字段分组取最大(小)值所在行的数据


(爱新觉罗.毓华 
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 行受影响)

*/
分享到:
评论
1 楼 hellostory 2012-03-19  
极度无语...

相关推荐

    mysql获取分组后每组的最大值实例详解

    主要介绍了 mysql获取分组后每组的最大值实例详解的相关资料,需要的朋友可以参考下

    mysql分组取每组前几条记录(排名) 附group by与order by的研究

    –按某一字段分组取最大(小)值所在行的数据 代码如下: /* 数据如下: 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 ...

    mysql获取group by总记录行数的方法

    一般来说,mysql获取group by内部可以获取到某字段的记录分组统计总数,而无法统计出分组的记录数。 mysql中可以使用SQL_CALC_FOUND_ROWS来获取查询的行数,在很多分页的程序中都这样写: 代码如下:SELECT COUNT(*) ...

    MYSQL常用命令大全

    MySQL以YYYY-MM-DD格式来显示DATE值,但是允许你使用字符串或数字把值赋给DATE列 4.CHAR(M) 型:定长字符串类型,当存储时,总是是用空格填满右边到指定的长度 5.BLOB TEXT类型,最大长度为65535(2^16-1)个字符...

    MySQL命令大全

    MySQL以YYYY-MM-DD格式来显示DATE值,但是允许你使用字符串或数字把值赋给DATE列 4.CHAR(M) 型:定长字符串类型,当存储时,总是是用空格填满右边到指定的长度 5.BLOB TEXT类型,最大长度为(2^16-1)个字符。 6...

    mysql数据库的基本操作语法

    auto_increment自增模式,设置自增后在插入数据的时候就不需要给该列插入值了。 4、 foreign key 约束 外键约束是保证一个或两个表之间的参照完整性,外键是构建于一个表的两个字段或是两个表的两个字段之间的参照...

    MySql基本查询、连接查询、子查询、正则表达查询讲解

    (1)max:求最大值 求每个部门的最高工资: [sql] view plain copy select EMP_NAME,EMP_DEP,max(EMP_SALARY) from EMPLOYEES group by EMP_DEP; (2)min:求最小值 求每个部门的最仰工资: [sql] view plain ...

    MYSQL,SQLSERVER,ORACLE常用的函数

    取子字符串,从start开始,取count个 SQL&gt; select substr('13088888888',3,8) from dual; SUBSTR(' -------- 08888888 12.REPLACE('string','s1','s2') string 希望被替换的字符或变量 s1 被替换的字符串 s2...

    程序员的SQL金典6-8

     4.3.2 数据分组与聚合函数  4.3.3 HAVING语句  4.4 限制结果集行数  4.4.1 MySQL  4.4.2 MS SQL Server 2000  4.4.3 MS SQL Server 2005  4.4.4 Oracle  4.4.5 DB2  4.4.6 数据库分页  4.5 抑制数据重复 ...

    程序员的SQL金典7-8

     4.3.2 数据分组与聚合函数  4.3.3 HAVING语句  4.4 限制结果集行数  4.4.1 MySQL  4.4.2 MS SQL Server 2000  4.4.3 MS SQL Server 2005  4.4.4 Oracle  4.4.5 DB2  4.4.6 数据库分页  4.5 抑制数据重复 ...

    程序员的SQL金典3-8

     4.3.2 数据分组与聚合函数  4.3.3 HAVING语句  4.4 限制结果集行数  4.4.1 MySQL  4.4.2 MS SQL Server 2000  4.4.3 MS SQL Server 2005  4.4.4 Oracle  4.4.5 DB2  4.4.6 数据库分页  4.5 抑制数据重复 ...

    程序员的SQL金典4-8

     4.3.2 数据分组与聚合函数  4.3.3 HAVING语句  4.4 限制结果集行数  4.4.1 MySQL  4.4.2 MS SQL Server 2000  4.4.3 MS SQL Server 2005  4.4.4 Oracle  4.4.5 DB2  4.4.6 数据库分页  4.5 抑制数据重复 ...

    程序员的SQL金典.rar

     本书特色:主要介绍SQL的语法规则及在实际开发中的应用,并且对SQL在MySQL、MS SQL Server、Oracle和DB2中的差异进行了分析;详细讲解数据库对增、删、改、查等SQL的支持并给出了相应的SQL应用案例;透彻分析函数...

    2009达内SQL学习笔记

    最大优点是可以包含其他 SELECT 语句,使用能够动态地建立 WHERE 子句。 如 SELECT prod_id,prod_price,prod_name FROM Products WHERE vend_id IN(‘DELL’,’RBER’,’TTSR’); 八、单行函数: 函数一般在数据...

    易语言程序免安装版下载

    注意:静态编译后的易语言EXE和DLL之间不能再共享“某些”句柄或资源,这一点和原动态连接时的程序行为不能保持一致,使用时请务必设法避免此类用法(MYSQL支持库我们作了特别处理)。 注意:静态编译后常量数据...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

     删除环境变量中的PATHT CLASSPATH中包含Oracle的值。  删除“开始”/“程序”中所有Oracle的组和图标。  删除所有与Oracle相关的目录,包括: C:\Program file\Oracle目录。 ORACLE_BASE目录。 C:\Documents ...

    SQL语句大全 珍藏版2019-02-28

    函数 AVG (平均) COUNT (计数) MAX (最大值) MIN (最小值) SUM (总合) SELECT "函数名"("栏位名") FROM "表格名" (10) COUNT .................................... .............. ..................................

Global site tag (gtag.js) - Google Analytics