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)

scoreidchinesemath
19080
210099
32998
48779
58999
14998
39856
27688
28090
39070
19090
16790


错误的SELECT
select scoreid,chinese,max(math) max_math from lkscore group by scoreid;

query result(5 records)

scoreidchinesemax_math
19098
210099
32998
48779
58999
上面的90明显不对。

方法一:

select scoreid,chinese,math max_math from
(
select * from lkscore order by math desc
) T
group by scoreid;

query result(5 records)

scoreidchinesemax_math
14998
210099
32998
48779
58999

方法二:


select * from lkscore a where a.math = (select max(math) from lkscore where scoreid = a.scoreid) order by scoreid asc;

query result(5 records)

scoreidchinesemax_math
14998
210099
32998
48779
58999

这个也是用MAX函数,而且还用到了相关子查询。
我们来看一下这两个的效率如何:


explain
select scoreid,chinese,math max_math from (select * from lkscore order by math desc) T group by scoreid;

query result(2 records)

idselect_typetabletypepossible_keyskeykey_lenrefrowsExtra
1PRIMARY<derived2>ALL(NULL)(NULL)(NULL)(NULL)12Using temporary; Using filesort
2DERIVEDlkscoreALL(NULL)(NULL)(NULL)(NULL)12Using filesort

很明显,有两个FULL TABLE SCAN。



explain
select scoreid,chinese,math max_math from lkscore a where a.math =
(select max(math) from lkscore where scoreid = a.scoreid) order by scoreid asc;

query result(2 records)

idselect_typetabletypepossible_keyskeykey_lenrefrowsExtra
1PRIMARYaindex(NULL)fk_class5(NULL)12Using where
2DEPENDENT SUBQUERYlkscorereffk_classfk_class5a.scoreid1Using where


第二个就用了KEY,子查询里只扫描了一跳记录。

很明显。在这种情况下第二个比第一个效率高点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值