SQL窗口函数与GROUP BY的核心区别,一文看懂+实战案例
在SQL数据分析中GROUP BY分组聚合和窗口函数是高频用法很多新手容易混淆二者看似都能做分组计算实则底层逻辑、使用场景天差地别。本文用通俗解释实战SQL帮你快速分清两者。一、核心本质区别1. 结果行数不同GROUP BY分组后合并行一个分组只返回1行结果会缩减数据集窗口函数不合并、不缩减行保留原表所有明细行仅在每行新增计算列。2. 计算逻辑不同GROUP BY对整个分组做全局聚合只能输出分组字段聚合结果窗口函数通过PARTITION BY划分窗口在窗口内计算支持聚合、排序、排名、滑动计算。3. 功能范围不同GROUP BY仅支持SUM/AVG/COUNT/MAX/MIN基础聚合窗口函数除聚合外还支持ROW_NUMBER/RANK/DENSE_RANK排名、LAG/LEAD跨行取值等。二、实战案例对比以学生成绩表student_score为例包含字段id(学号)、name(姓名)、class(班级)、score(分数)。测试数据CREATETABLEstudent_score(idINT,nameVARCHAR(10),classVARCHAR(10),scoreINT);INSERTINTOstudent_scoreVALUES(1,张三,一班,90),(2,李四,一班,85),(3,王五,二班,92),(4,赵六,二班,88);场景1统计每个班级的总分、平均分用GROUP BY需求只看班级汇总数据不需要学生明细。SELECTclass,SUM(score)ASclass_total,AVG(score)ASclass_avgFROMstudent_scoreGROUPBYclass;结果仅返回2行一班、二班各1行无学生明细。场景2保留学生明细同时显示班级总分、平均分用窗口函数需求保留所有学生行附加班级聚合数据。SELECTid,name,class,score,-- 按班级分区计算窗口内总分SUM(score)OVER(PARTITIONBYclass)ASclass_total,-- 按班级分区计算窗口内平均分AVG(score)OVER(PARTITIONBYclass)ASclass_avgFROMstudent_score;结果保留4行学生明细每行都携带对应班级的聚合值。场景3班级内成绩排名窗口函数独有功能GROUP BY无法实现排名窗口函数可轻松完成SELECTname,class,score,ROW_NUMBER()OVER(PARTITIONBYclassORDERBYscoreDESC)ASrank_numFROMstudent_score;三、使用场景总结用GROUP BY需要汇总统计只看分组整体结果不需要原始明细用窗口函数需要保留明细行同时做分组聚合、排名、跨行对比等操作。二者并非替代关系而是互补GROUP BY做汇总缩减窗口函数做明细增强实际业务中可根据需求灵活选择。