【SQL专栏】3. 分组统计总写错?一文搞懂GROUP BY与WHERE/HAVING的本质区别
今日核心知识点GROUP BY分组 COUNT/AVG聚合函数 HAVING分组过滤面向SQL入门新手结合运营看板真实业务场景彻底分清WHERE和HAVING的用法边界附4道大厂真题错题矫正一、真实业务场景运营总监每周更新业务看板有两个高频统计需求商品维度统计每个品类有多少个SKU、平均售价是多少按SKU数量排序看品类分布人事维度统计各部门平均薪资筛选出平均薪资超过1万元的部门这类「每个XX的XX」式汇总需求单靠WHERE筛选解决不了必须用分组聚合的组合语法这也是SQL从“查数据”到“做统计”的核心转折点。二、数据表结构今日涉及两张业务表分别对应商品库和员工人事数据1. 商品表 productsCREATETABLEproducts(product_idINTPRIMARYKEYAUTO_INCREMENT,nameVARCHAR(128)NOTNULL,brandVARCHAR(64),categoryVARCHAR(64)NOTNULL,priceDECIMAL(10,2)NOTNULL,salesINTDEFAULT0,INDEXidx_category(category));字段大白话商品ID、商品名称、品牌、所属品类、售价、销量2. 员工表 employeesCREATETABLEemployees(idINTPRIMARYKEYAUTO_INCREMENT,nameVARCHAR(64)NOTNULL,dept_idINTNOTNULL,salaryDECIMAL(12,2)NOTNULL,hire_dateDATENOTNULL,INDEXidx_dept(dept_id),INDEXidx_salary(salary));字段大白话员工ID、姓名、部门ID、薪资、入职日期三、今日必学3个核心知识点新手避坑重点1. 聚合函数对一组数据做统计计算作用把多行数据聚合成一个统计结果必须配合GROUP BY使用全表统计除外。今日高频用到的4个聚合函数COUNT(*)统计行数即SKU数量、员工人数AVG(字段)计算平均值如平均售价、平均薪资SUM(字段)计算总和如总销量、总薪资MAX/MIN(字段)求最大值、最小值新手注意聚合函数不能写在WHERE条件里这是90%入门者都会犯的错误。2. GROUP BY按维度分组统计作用按照某个字段把数据分成若干组再对每组分别执行聚合计算实现「每个品类、每个部门」的统计。语法规则SELECT后面的非聚合字段必须全部出现在GROUP BY子句中。典型句式看到需求里有「每个XX、各XX、按XX分组」直接用GROUP BY。3. WHERE 与 HAVING 的本质区别核心考点这是SQL入门最容易混淆的知识点一句话讲清WHERE分组前筛行。对原始表的每一行数据做过滤过滤完再分组不能使用聚合函数HAVING分组后筛组。对分组聚合后的结果做过滤必须配合GROUP BY使用过滤条件通常是聚合结果执行顺序验证FROM 表 → WHERE 过滤行 → GROUP BY 分组 → 聚合计算 → HAVING 过滤组 → ORDER BY 排序4. 排序小技巧聚合结果别名复用给聚合结果起别名如COUNT(*) AS cnt后ORDER BY可以直接用别名排序不用重复写聚合公式代码更简洁。四、基础语法演示演示1 各品类SKU数与平均售价按数量降序组合知识点GROUP BY COUNT/AVG聚合 ORDER BYSELECTcategory,COUNT(*)AScnt,AVG(price)ASavg_priceFROMproductsGROUPBYcategoryORDERBYcntDESC;演示2 平均薪资超过1万的部门组合知识点GROUP BY HAVING 分组过滤SELECTdept_id,AVG(salary)ASavg_salFROMemployeesGROUPBYdept_idHAVINGAVG(salary)10000;五、大厂真题刷题附错题矫正Q009 阿里巴巴真题核心考点GROUP BY 聚合函数 ORDER BY排序题目按品类分组统计每个品类的商品数量和平均价格按数量降序。❌ 新手易错写法selectsumproduct_id,avg(sales)fromproductsgroupbycategoryorderbydesc错误原因统计商品数量应该用COUNT(*)不是SUM(product_id)sum是求和count才是计数SELECT缺少分组字段category结果无法对应品类ORDER BY后没指定排序字段语法错误平均价格对应字段是price不是sales✅ 正确答案SELECTcategory,COUNT(*)AScnt,AVG(price)ASavg_priceFROMproductsGROUPBYcategoryORDERBYcntDESC;解题拆解确定分组维度GROUP BY category按品类分组两个聚合计算COUNT(*)统计SKU数量AVG(price)计算平均售价SELECT中包含分组字段category保证结果可对应用聚合别名cnt做降序排序Q010 腾讯真题核心考点GROUP BY HAVING 分组后筛选题目按部门分组筛选平均薪资超过10000的部门。❌ 新手易错写法selectdept_id avg(salary)fromemployessorderbydept_idhavingavgsalary10000错误原因表名拼写错误employess → employees语法顺序错误HAVING必须紧跟在GROUP BY之后ORDER BY在最后使用了中文逗号、中文括号SQL语法不识别缺少GROUP BY分组子句✅ 正确答案SELECTdept_id,AVG(salary)ASavg_salFROMemployeesGROUPBYdept_idHAVINGAVG(salary)10000;解题拆解先按部门dept_id分组计算每个部门的平均薪资AVG(salary)用HAVING过滤分组结果只保留平均薪资大于10000的部门注意平均薪资是聚合结果只能用HAVING过滤不能写在WHERE里Q011 美团真题核心考点GROUP BY 聚合 ORDER BY题目统计各品类SKU数量与均价结果按SKU数从多到少排列。❌ 新手易错写法selectproduct_id,avg(price)fromproductsgroupbycategoryorderbysum(product_id)desc错误原因SELECT写了product_id但分组字段是category非聚合字段不匹配结果无意义SKU数量用COUNT(*)统计不是SUM(product_id)求和排序字段错误应该按SKU数量排序而非商品ID求和✅ 正确答案SELECTcategory,COUNT(*)ASsku_cnt,AVG(price)ASavg_priceFROMproductsGROUPBYcategoryORDERBYsku_cntDESC;解题拆解和Q009考点完全一致属于业务场景化表述。核心是区分「计数」用COUNT、「求和」用SUM不要混淆两个聚合函数的作用。Q012 京东真题核心考点GROUP BY HAVING 别名使用题目找出均薪高于1万元的dept_id及其平均薪资。✅ 正确答案SELECTdept_id,AVG(salary)ASavg_salFROMemployeesGROUPBYdept_idHAVINGavg_sal10000;解题拆解按部门分组计算平均薪资并起别名avg_salHAVING可以直接使用聚合别名进行过滤多数数据库支持代码更简洁最终结果只保留均薪达标部门的部门ID和对应平均薪资六、今日学习总结1. 新手避坑清单❌ 不要用SUM统计行数计数统一用COUNT(*)❌ 不要在WHERE里写聚合函数条件分组后过滤必须用HAVING❌ 不要SELECT非聚合、且不在GROUP BY里的字段结果逻辑不成立❌ 不要搞反顺序GROUP BY → HAVING → ORDER BY2. 两类高频分组题型分组统计排序类GROUP BY 聚合函数 ORDER BY适用于品类统计、部门人数统计等看板需求分组条件筛选类GROUP BY HAVING适用于筛选达标部门、高产出品类等过滤需求3. 执行顺序记忆口诀先查表再筛行分好组算聚合筛完组再排序4. 落地价值掌握分组聚合后就能独立完成运营看板、人事统计、财务汇总等各类报表需求是SQL从“取明细”到“做分析”的关键进阶点。