MAX函数和GROUP BY 语句一起使用的一个误区
使用MAX 函数和 GROUP 的时候会有不可预料的数据被SELECT 出来。
下面举个简单的例子:
想知道每个SCOREID 的 数学成绩最高的分数。
表信息:
/*DDL Information For - test.lkscore*/
--------------------------------------
Table Create Table
------- -----------------------------------------------------------------------------
lkscore CREATE TABLE `lkscore` (
`scoreid` int(11) DEFAULT NULL,
`chinese` int(11) DEFAULT '0',
`math` int(11) DEFAULT '0',
KEY `fk_class` (`scoreid`),
CONSTRAINT `fk_class` FOREIGN KEY (`scoreid`) REFERENCES `lkclass` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312
select * from lkscore; |
query result(12 records)
| scoreid | chinese | math |
| 1 | 90 | 80 |
| 2 | 100 | 99 |
| 3 | 29 | 98 |
| 4 | 87 | 79 |
| 5 | 89 | 99 |
| 1 | 49 | 98 |
| 3 | 98 | 56 |
| 2 | 76 | 88 |
| 2 | 80 | 90 |
| 3 | 90 | 70 |
| 1 | 90 | 90 |
| 1 | 67 | 90 |
错误的SELECT
select scoreid,chinese,max(math) max_math from lkscore group by scoreid; |
query result(5 records)
| scoreid | chinese | max_math |
| 1 | 90 | 98 |
| 2 | 100 | 99 |
| 3 | 29 | 98 |
| 4 | 87 | 79 |
| 5 | 89 | 99 |
上面的90明显不对。
方法一:
select scoreid,chinese,math max_math from (select * from lkscore order by math desc) T group by scoreid; |
query result(5 records)
| scoreid | chinese | max_math |
| 1 | 49 | 98 |
| 2 | 100 | 99 |
| 3 | 29 | 98 |
| 4 | 87 | 79 |
| 5 | 89 | 99 |
方法二:
select * from lkscore a where a.math = (select max(math) from lkscore where scoreid = a.scoreid) order by scoreid asc; |
query result(5 records)
| scoreid | chinese | max_math |
| 1 | 49 | 98 |
| 2 | 100 | 99 |
| 3 | 29 | 98 |
| 4 | 87 | 79 |
| 5 | 89 | 99 |
这个也是用MAX函数,而且还用到了相关子查询。
我们来看一下这两个的效率如何:
explain |
query result(2 records)
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
| 1 | PRIMARY | <derived2> | ALL | (NULL) | (NULL) | (NULL) | (NULL) | 12 | Using temporary; Using filesort |
| 2 | DERIVED | lkscore | ALL | (NULL) | (NULL) | (NULL) | (NULL) | 12 | Using filesort |
很明显,有两个FULL TABLE SCAN。
|
query result(2 records)
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
| 1 | PRIMARY | a | index | (NULL) | fk_class | 5 | (NULL) | 12 | Using where |
| 2 | DEPENDENT SUBQUERY | lkscore | ref | fk_class | fk_class | 5 | a.scoreid | 1 | Using where |
第二个就用了KEY,子查询里只扫描了一跳记录。
很明显。在这种情况下第二个比第一个效率高点。
MAX函数和GROUP BY 语句一起使用的一个误区的更多相关文章
- MySQL中MAX函数与Group By一起使用的注意事项(转)
mysql> select * from test; +----+-------+------+-------+ | id | name | age | class | +----+------ ...
- GROUP BY语句与HAVING语句的使用
一.GROUP BY GROUP BY语句用来与聚合函数(aggregate functions such as COUNT, SUM, AVG, MIN, or MAX.)联合使用来得到一个或多个列 ...
- SQL中GROUP BY语句与HAVING语句的使用
GROUP BY语句,经过研究和练习,终于明白如何使用了,在此记录一下同时添加了一个自己举的小例子,通过写这篇文章来加深下自己学习的效果,还能和大家分享下,同时也方便以后查阅,一举多得 一.GROUP ...
- 【转】SQL中GROUP BY语句与HAVING语句的使用
一.GROUP BY GROUP BY语句用来与聚合函数(aggregate functions such as COUNT, SUM, AVG, MIN, or MAX.)联合使用来得到一个或多个列 ...
- group by语句,聚合函数与其他语句(关系,执行过程)
(本文一切基于SQL SERVER 2008 R2) 先来看一个语句执行过程发生的错误提示: 消息 8120,级别 16,状态 1,第 2 行 选择列表中的列 'SC.CNO' 无效,因为该列没有包含 ...
- 深入理解group by 语句的执行顺序 from→where→group by→select(含聚合函数)
由于之前没有对group by 语句的执行顺序(执行原理)做深入的了解,所以导致在实际应用过程中出现了一些问题.举个简单的粟子,比如一个表testA中的所有数据如下图: 我现在想从testA中查询us ...
- [数据库]关于MAX()函数的一个坑
之前写了这么一条sql语句,目的是取出表中itemid最大的那一条数据. SELECT date, MAX(itemid) AS itemid, group FROM mytable GROUP BY ...
- mysql之聚合函数、group by、having
sql中提供聚合函数可以用来统计,求和,求最值等 那么聚合函数有哪些呢? COUNT 统计行数量 SUM 求某一列的和 AVG 求某一列的平均值 MAX 求某 ...
- MySQL GROUP BY语句
GROUP BY 语句根据一个或多个列对结果集进行分组 在分组的列上我们可以使用COUNT.SUM.AVG等函数 SELECT column_name,function(column_name) FR ...
随机推荐
- Codeforces Round #238 (Div. 1)
感觉这场题目有种似曾相识感觉,C题还没看,日后补上.一定要坚持做下去. A Unusual Product 题意: 给定一个n*n的01矩阵,3种操作, 1 i 将第i行翻转 2 i 将第i列翻转 3 ...
- Bamboo简介
前言 前面介绍了JIRA管理平台,那么本篇就来介绍关于自动编译项目的工具-Bamboo. 正题 1.简介 Atlassian Bamboo 是一款持续集成构建服务器软件(Build Serve ...
- plsql exist和in 的区别
<![endif]--> <![endif]--> 发现公司同事很喜欢用exists 和in 做子查询关联,我觉得很有必要研究下 两者的区别,供参考和备忘 /* (这段信息来自 ...
- 【HDOJ】1018 Big Number
数学题,还是使用log避免大数,但是不要忘记需要+1,因为0也是1位,log(100)= 2,但却是3位. #include <stdio.h> #include <math.h&g ...
- poj2411Mondriaan's Dream(状压)
http://poj.org/problem?id=2411 下次还是去学习下dfs的写法吧 自己乱写的好像有点乱 乱七八糟改了一通过了 以1 1 表示横着的 1 0 表示竖着的 枚举每一行的状态 再 ...
- hadoop2.2基准测试
<hadoop the definitive way>(third version)中的Benchmarking a Hadoop Cluster Test Cases的class在新的版 ...
- cat ,more, Less区别
使用cat more less都可以查看文本内容,但是它们三者有什么区别呢?more和less的功能完全重复吗?以下是我个人的总结,欢迎大家一起来分享 cat 连续显示.查看文件内容mo ...
- BZOJ_1096_[ZJOI2007]_仓库建设_(斜率优化动态规划+单调队列+特殊的前缀和技巧)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1096 有\(n\)个工厂,给出第\(i\)个工厂的到1号工厂的距离\(x[i]\),货物数量\ ...
- SCOI2007排列perm
1072: [SCOI2007]排列perm Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 805 Solved: 497[Submit][Stat ...
- 定制属于自己的自动化安装的linux系统镜像
使用软件和平台 1.基于平台: Vmware workstation 8.0 2.基于系统镜像: rhel-server-5.8-i386 ...