MySQL GROUP BY 语句

GROUP BY 语句根据一个或多个列对结果集进行分组。

在分组的列上我们可以使用 COUNT, SUM, AVG,等函数。

GROUP BY 语句是 SQL 查询中用于汇总和分析数据的重要工具,尤其在处理大量数据时,它能够提供有用的汇总信息。

GROUP BY 语法

									SELECT column1, aggregate_function(column2)
FROM table_name
WHERE condition
GROUP BY column1;
								
  • column1 :指定分组的列。
  • aggregate_function(column2) :对分组后的每个组执行的聚合函数。
  • table_name :要查询的表名。
  • condition :可选,用于筛选结果的条件。

假设有一个名为 orders 的表,包含以下列: order_id、customer_id、order_date 和 order_amount

我们想要按照 customer_id 进行分组,并计算每个客户的订单总金额,SQL 语句如下:

实例

SELECT customer_id , SUM ( order_amount ) AS total_amount
FROM orders
GROUP BY customer_id;

以上实例中,我们使用 GROUP BY customer_id 将结果按 customer_id 列分组,然后使用 SUM(order_amount) 计算每个组中 order_amount 列的总和。

AS total_amount 是为了给计算结果取一个别名,使查询结果更易读。

注意事项:

  • GROUP BY 子句通常与聚合函数一起使用,因为分组后需要对每个组进行聚合操作。
  • SELECT 子句中的列通常要么是分组列,要么是聚合函数的参数。
  • 可以使用多个列进行分组,只需在 GROUP BY 子句中用逗号分隔列名即可。

实例

SELECT column1 , column2 , aggregate_function ( column3 )
FROM TABLE_NAME
WHERE condition
GROUP BY column1 , column2;

实例演示

本章节实例使用到了以下表结构及数据,使用前我们可以先将以下数据导入数据库中。

实例

SET NAMES utf8;
SET FOREIGN_KEY_CHECKS = ;

-- ----------------------------
--  Table structure for `employee_tbl`
-- ----------------------------
DROP TABLE IF EXISTS `employee_tbl` ;
CREATE TABLE `employee_tbl` (
  `id` INT ( 11 ) NOT NULL ,
  `name` CHAR ( 10 ) NOT NULL DEFAULT '' ,
  `date` datetime NOT NULL ,
  `signin` tinyint ( 4 ) NOT NULL DEFAULT '0' COMMENT '登录次数' ,
  PRIMARY KEY ( `id` )
) ENGINE = InnoDB DEFAULT CHARSET = utf8;

-- ----------------------------
--  Records of `employee_tbl`
-- ----------------------------
BEGIN ;
INSERT INTO `employee_tbl` VALUES ( '1' , '小明' , '2016-04-22 15:25:33' , '1' ) , ( '2' , '小王' , '2016-04-20 15:25:47' , '3' ) , ( '3' , '小丽' , '2016-04-19 15:26:02' , '2' ) , ( '4' , '小王' , '2016-04-07 15:26:14' , '4' ) , ( '5' , '小明' , '2016-04-11 15:26:40' , '4' ) , ( '6' , '小明' , '2016-04-04 15:26:54' , '2' ) ;
COMMIT;

SET FOREIGN_KEY_CHECKS = 1 ;

导入成功后,执行以下 SQL 语句:

		mysql> set names utf8;
mysql> SELECT * FROM employee_tbl;
+----+--------+---------------------+--------+
| id_name  _date               _signin |
+----+--------+---------------------+--------+
|  1_小明_2016-04-22 15:25:33_     1 |
|  2_小王_2016-04-20 15:25:47_     3 |
|  3_小丽_2016-04-19 15:26:02_     2 |
|  4_小王_2016-04-07 15:26:14_     4 |
|  5_小明_2016-04-11 15:26:40_     4 |
|  6_小明_2016-04-04 15:26:54_     2 |
+----+--------+---------------------+--------+
6 rows in set (0.00 sec)
	

接下来我们使用 GROUP BY 语句 将数据表按名字进行分组,并统计每个人有多少条记录:

		mysql> SELECT name, COUNT(*) FROM   employee_tbl GROUP BY name;
+--------+----------+
| name  _COUNT(*) |
+--------+----------+
| 小丽_       1 |
| 小明_       3 |
| 小王_       2 |
+--------+----------+
3 rows in set (0.01 sec)
	

使用 WITH ROLLUP

WITH ROLLUP 可以实现在分组统计数据基础上再进行相同的统计(SUM,AVG,COUNT…)。

例如我们将以上的数据表按名字进行分组,再统计每个人登录的次数:

		mysql> SELECT name, SUM(signin) as signin_count FROM  employee_tbl GROUP BY name WITH ROLLUP;
+--------+--------------+
| name  _signin_count |
+--------+--------------+
| 小丽_           2 |
| 小明_           7 |
| 小王_           7 |
| NULL  _          16 |
+--------+--------------+
4 rows in set (0.00 sec)
	

其中记录 NULL 表示所有人的登录次数。

我们可以使用 coalesce 来设置一个可以取代 NUll 的名称,coalesce 语法:

		select coalesce(a,b,c);
	

参数说明:如果 a==null,则选择 b;如果 b==null,则选择 c;如果 a!=null,则选择 a;如果 a b c 都为 null ,则返回为 null(没意义)。

以下实例中如果名字为空我们使用总数代替:

		mysql> SELECT coalesce(name, '总数'), SUM(signin) as signin_count FROM  employee_tbl GROUP BY name WITH ROLLUP;
+--------------------------+--------------+
| coalesce(name, '总数')_signin_count |
+--------------------------+--------------+
| 小丽                  _           2 |
| 小明                  _           7 |
| 小王                  _           7 |
| 总数                  _          16 |
+--------------------------+--------------+
4 rows in set (0.01 sec)