mysql group by 用法解析(详细)

本文详细介绍了SQL中的GROUP BY语句用法,通过实例展示了如何利用GROUP BY进行数据分组统计,包括求每个部门的最高薪水、总薪水以及结合WHERE和HAVING子句进行更复杂的查询。同时,强调了GROUP BY与聚合函数的配合使用以及在限定条件下的查询操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

group by 用法解析

group by语法可以根据给定数据列的每个成员对查询结果进行分组统计,最终得到一个分组汇总表。

SELECT子句中的列名必须为分组列列函数。列函数对于GROUP BY子句定义的每个组各返回一个结果。
某个员工信息表结构和数据如下:

id name dept salary edlevel hiredate
1 张三 开发部 2000 3 2009-10-11
2 李四 开发部 2500 3 2009-10-01
3 王五 设计部 2600 5 2010-10-02
4 王六 设计部 2300 4 2010-10-03
5 马七 设计部 2100 4 2010-10-06
6 赵八 销售部 3000 5 2010-10-05
7 钱九 销售部 3100 7 2010-10-07
8 孙十 销售部 3500 7 2010-10-06

例如,我想列出每个部门最高薪水的结果,sql语句如下:

SELECT DEPT, MAX(SALARY) AS MAXIMUM
FROM STAFF
GROUP BY DEPT


查询结果如下:
      DEPT  MAXIMUM 
      开发部 2500
      设计部 2600
      销售部 3500

解释一下这个结果:

  • 1、满足“SELECT子句中的列名必须为分组列列函数”,因为SELECT有GROUP BY DEPT中包含的列DEPT。
  • 2、“列函数对于GROUP BY子句定义的每个组各返回一个结果”,根据部门分组,对每个部门返回一个结果,就是每个部门的最高薪水。
    注意:计算的是每个部门(由 GROUP BY 子句定义的组)而不是整个公司的 MAX(SALARY)。
    例如,查询每个部门的总的薪水数:
SELECT DEPT, sum( SALARY ) AS total
FROM STAFF
GROUP BY DEPT

查询结果如下:
DEPT  total 
开发部 4500
设计部 7000
销售部 9600

将 WHERE 子句与 GROUP BY 子句一起使用

分组查询可以在形成组和计算列函数之前具有消除非限定行的标准 WHERE 子句。必须在GROUP BY 子句之前指定 WHERE 子句。
例如,查询公司2010年入职的各个部门每个级别里的最高薪水

SELECT DEPT, EDLEVEL, MAX( SALARY ) AS MAXIMUM
FROM staff
WHERE HIREDATE > '2010-01-01'
GROUP BY DEPT, EDLEVEL
ORDER BY DEPT, EDLEVEL

DEPT  EDLEVEL  MAXIMUM 
设计部    4    2300
设计部    5    2600
销售部    5    3000
销售部    7    3500

注意:在SELECT语句中指定的每个列名也在GROUP BY子句中提到。未在这两个地方提到的列名将产生错误。GROUP BY子句对DEPT和EDLEVEL的每个唯一组合各返回一行。

在GROUP BY子句之后使用HAVING子句

可应用限定条件进行分组,以便系统仅对满足条件的组返回结果。为此,在GROUP BY子句后面包含一个HAVING子句。HAVING子句可包含一个或多个用AND和OR连接的谓词。每个谓词将组特性(如AVG(SALARY))与下列之一进行比较:
例如:寻找雇员数超过2个的部门的最高和最低薪水:

SELECT DEPT, MAX( SALARY ) AS MAXIMUM, MIN( SALARY ) AS MINIMUM
FROM staff
GROUP BY DEPT
HAVING COUNT( * ) >2
ORDER BY DEPT

查询结果如下:
  DEPT  MAXIMUM  MINIMUM 
  设计部  2600    2100
  销售部  3500    3000

如:寻找雇员平均工资大于3000的部门的最高和最低薪水:

SELECT DEPT, MAX( SALARY ) AS MAXIMUM, MIN( SALARY ) AS MINIMUM
FROM staff
GROUP BY DEPT
HAVING AVG( SALARY ) >3000
ORDER BY DEPT

查询结果如下:
  DEPT  MAXIMUM  MINIMUM 
  销售部   3500   3000

原文链接:https://blog.csdn.net/hjwang1/article/details/7270921?

<think>嗯,用户想了解MySQLGROUP BY用法及示例。首先,我需要回顾一下GROUP BY的基本概念。根据引用中的资料,GROUP BY通常与聚合函数一起使用,比如COUNT、SUM、AVG等,用来对结果集进行分组。基本语法结构应该是SELECT后面跟列名和聚合函数,然后是FROM和GROUP BY子句。 然后,用户可能需要知道基本用法。例如,引用2里的示例,按部门分组计算平均工资。我应该把这个例子详细解释一下,确保用户明白如何应用。同时,引用3提到了基本语法,可能需要整理一下,用更清晰的方式呈现,比如分步骤说明。 接下来,用户可能对GROUP BY的多个字段分组感兴趣。比如,按部门和职位分组,这时候需要说明如何同时使用多个列。引用3里提到可以GROUP BY多个列,应该给出相应的示例,比如统计每个部门不同职位的平均工资。 另外,用户可能不知道在使用GROUP BY时,SELECT后面只能放聚合函数或GROUP BY的列。引用1和引用3都提到这个问题,如果不遵守可能导致不确定的结果。这里需要强调SQL标准的重要性,避免用户在使用时出错。 还有过滤分组后的数据,使用HAVING子句。这和WHERE的区别需要解释清楚,比如WHERE在分组前过滤,HAVING在分组后。引用里没有直接提到HAVING,但这是常见的用法,应该补充进去,并给出例子,比如筛选平均工资大于5000的部门。 然后是关于性能的问题,引用5提到GROUP BY多个字段可能导致索引失效,只有单个字段索引有效。需要提醒用户注意这一点,优化查询性能。可能还需要提到如何优化,比如确保GROUP BY的列有索引,或者减少分组字段的数量。 最后,示例部分要综合多个引用中的内容,展示不同情况下的使用方式。比如基本分组、多字段分组、结合HAVING过滤,以及排序。引用4中的ORDER BY示例可以结合起来,说明如何对分组后的结果排序。 还要注意用户可能遇到的常见错误,比如在SELECT中使用非聚合列,或者混淆WHERE和HAVING。需要指出这些陷阱,帮助用户避免。同时,引用1提到MySQL允许非标准用法,但建议遵循SQL标准,确保数据准确性。 总结一下,回答的结构应该包括基本概念、语法结构、常见用法(单字段、多字段分组)、过滤、性能优化,以及示例代码。确保每个部分都有对应的引用支持,并在末尾添加相关问题,引导用户进一步学习。</think>### MySQL GROUP BY 使用方法及示例 #### 一、基本概念 `GROUP BY` 用于将查询结果按指定列分组,并结合聚合函数(如 $COUNT()$、$SUM()$、$AVG()$、$MAX()$、$MIN()$)对每组数据进行统计[^3]。例如统计每个部门的平均工资,或按地区分组计算订单总量。 #### 二、基本语法 ```sql SELECT column_name(s), AGGREGATE_FUNCTION(column_name) FROM table_name WHERE condition GROUP BY column_name(s) ORDER BY column_name(s); ``` - `column_name(s)`:分组依据的列 - `AGGREGATE_FUNCTION`:应用于分组的聚合函数[^3] #### 三、常见用法 1. **单字段分组** 示例:统计每个部门的平均工资 ```sql SELECT department, AVG(salary) AS average_salary FROM employees GROUP BY department; ``` 输出结果按 `department` 分组,显示每个部门对应的平均工资[^2]。 2. **多字段分组** 示例:统计每个部门不同职位的平均工资 ```sql SELECT department, job_title, AVG(salary) FROM employees GROUP BY department, job_title; ``` 此时结果会按 `department` 和 `job_title` 的联合值分组[^3]。 3. **结合 HAVING 过滤分组** `HAVING` 用于对分组后的结果进行筛选(类似 `WHERE` 但作用在分组后): ```sql SELECT department, AVG(salary) FROM employees GROUP BY department HAVING AVG(salary) > 5000; ``` 仅保留平均工资超过 5000 的部门。 #### 四、注意事项 1. **SELECT 列限制** SELECT 后的列必须出现在 `GROUP BY` 子句中,或是聚合函数的参数。否则可能导致不确定结果(MySQL 允许非标准写法,但不符合 SQL 规范)[^1]。 2. **性能优化** - 对 `GROUP BY` 列建立索引可提升性能 - 多字段分组时,若所有字段都有索引仍可能失效(建议优先单字段分组)[^5] #### 五、完整示例 ```sql -- 统计每个城市每个产品的总销量,并筛选销量超过 100 的记录 SELECT city, product, SUM(quantity) AS total_quantity FROM sales WHERE sale_date >= '2023-01-01' GROUP BY city, product HAVING total_quantity > 100 ORDER BY city, total_quantity DESC; ``` #### 六、与其他子句关系 - `WHERE`:在分组前过滤原始数据 - `ORDER BY`:在分组后对结果排序[^4] - `JOIN`:可先连接多表再进行分组统计
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值