两个思路:从选项推答案(使用选择题);如果是问答题如何分析。
1、从选项推答案
1.1 选项中非标准语句问题
① GROUP BY后SELECT列有非聚合列:标准SQL - SELECT 聚合列,聚合函数(任意列)FROM 表 GROUP BY;在mysql中sql_mode配置为ONLY_FULL_GROUP_BY(严格模式)时会检查GROUP BY的合法性,如果没有配置,MySQL允许target list中输出的表达式是除聚集函数或group by column以外的列或表达式。
② GROUP BY后有DESC关键字:标准SQL - DESC/ASC一定跟在ORDER BY后;在mysql8.0之前GROUP BY支持隐示排序(默认生成表会自动排序)和显示排序(GROUP BY后跟DESC/ASC), mysql8.0不再支持,原因大概是之前版本有个问题(不允许使用ORDER BY进行ROLLUP)所以用隐示排序作为替代后来当缺陷解决了就删除了隐示排序和显示排序【这问题是当BUG解决的,程序员埋坑挖土造新坑,永无止境也~】,详细见https://mysqlserverteam.com/removal-of-implicit-and-explicit-sorting-for-group-by/。
③ sum(download_count) download_sum 别名没用AS:AS是别名关键字,增加了可读性;如果没有AS效果是一样的只是不太好看
1.2 分析选项推答案
① 聚合:从选项中可以看出执行第一步都是SELECT GROUP BY;所以这里对于快速分析并没有太大帮助,可以直接分析下一步了。
SELECT GROUP BY拆解过程如下:
- group by中间(逻辑)表。聚合过程好比excel中合并单元格(聚合列同值行合并),又这里默认会隐示排序,看起来好像是建了个索引。
- SELECT生成表
② GROUP or JOIN or SELECT:从选项中看出第二步执行可能性分别是,GROUP、JOIN 、SELECT;这时候要分析这3个操作分别用于什么情况。
- SELECT...GROUP,按列值分成若干逻辑表并可以在同组表内查询筛选若干结果
- SELECT...WHERE,在整张表内查询筛选结果,
- SELECT...JOIN,联结分外联结和自联结;外联结是为了向其他表查询本表没有的数据信息,这里显然不需要;自联结一般是不同列有关联关系,同一列为关联关系的意义不大,这里也不符合;如果真的同一列连接(如下表),其中(t2.download_sum仅仅是t1.download_count多行的累加,并没有得到额外信息;反而是冗余扩张)
综上并结合题干,期望需与app_id列聚合的结果,GROUP就是是最好的选择;至于出现DESC,选择最大值提高查询速度吧。
2、如何解决此类问答题?(按照选项套的思路,分析下来这个选项除了有部分非标准SQL语句,所以以下从题干总结思路)
s1、每个应用(版本号对应总下载量)最大值 -> 筛选出最大值的列是(版本号对应总下载量),(版本号对应总下载量)这个列从原表中无法直接得出,故需要一个子查询;假设子查询已成功,有列1 -> 问题转换为,每个应用(app_id)中列1最大值 -> 查询结果app_id含原表所有值且唯一,用GROUP BY;列1的最大值且跟着GROUP BY,必选聚合函数MAX;
总查询:SELECT a.app_id,a.MAX(列1) FROM(子查询)AS a GROUP BY app_id;
s2、版本号对应总下载量 -> 引申为每个版本(version_code)对应总下载量 -> 查询结果version_code含原表所有值且唯一,用GROUP BY;总下载量即为下载量(download_count)列值的总合,用SUM;又因为(版本号对应总下载量)是子查询,需要向主查询传递app_id且app_id是聚合version_code的前提条件,所以聚合列是(app_id,version_code)
子查询:SELECT app_id, version_code, SUM(download_count) FROM 原表 GROUP BYapp_id,version_code;
SELECT a.app_id, a.version, MAX(a.download_sum) FROM (SELECT app_id, version, SUM(download) AS download_sum FROM app GROUP BY app_id, version) AS a GROUP BY app_id;
以上有主观成分(如错误欢迎讨论)