MySQL GROUP BY
This article will describes MySQL GROUP BY clause which can group some rows by specified columns or expression.
Sometimes, we need to summarize some rows base on one or more columns. This is often used in statistics, consider the following use cases:
- Get the average grade by class.
- Summarize total score by student.
- Summarize sales by year or month.
- Summarize the number of users by country or region.
You can use the GROUP BY clauses in these use cases.
In MySQL, GROUP BY clauses are used to group some rows into summary rows by columns values or expressions.
GROUP BY syntax
The GROUP BY Clause is used in SELECT statement. The syntax of the GROUP BY clause is as follows:
SELECT select_list
FROM table_name
[WHERE row_condition]
GROUP BY group_expression [, group_expression ...]
[HAVING group_condition]
[ORDER BY order_expression]
[LIMIT row_count];
Here:
group_expressionafter theGROUP BYkeyword is a column or expression used to form groups. You can group by one or more expressions.select_listcan contain grouping columns and aggregate expressions such asSUM()orCOUNT().- When
ONLY_FULL_GROUP_BYis enabled, each nonaggregate column in theSELECTlist must be in the grouping list or functionally dependent on its columns. See MySQL GROUP BY handling for details. - The
WHEREclause is used to filter the rows in the result set and it is optional. - The optional
HAVINGclause filters groups after aggregation; see MySQL HAVING.
Here is some aggregate functions often used in the GROUP BY clause:
SUM()AVG()MAX()MIN()COUNT()
GROUP BY examples
In the following example, we will use actor and paypment tables from Sakila sample database.
Simple GROUP BY example
We use the GROUP BY clause to list all last names in the actor table.
SELECT last_name
FROM actor
GROUP BY last_name;
+--------------+
| last_name |
+--------------+
| AKROYD |
| ALLEN |
| ASTAIRE |
| BACALL |
| BAILEY |
...
| ZELLWEGER |
+--------------+
121 rows in set (0.00 sec)In this example, the GROUP BY clause grouped all rows based on last_name column values.
The output of this example is as same as following statement using DISTINCT:
SELECT DISTINCT last_name FROM actor;
using aggregate functions
If you want to know the count of every last name in the above example, you can use aggregate functions COUNT(). Here is the statement:
SELECT last_name, COUNT(*)
FROM actor
GROUP BY last_name
ORDER BY COUNT(*) DESC;
+--------------+----------+
| last_name | COUNT(*) |
+--------------+----------+
| KILMER | 5 |
| NOLTE | 4 |
| TEMPLE | 4 |
| AKROYD | 3 |
| ALLEN | 3 |
| BERRY | 3 |
...
| WRAY | 1 |
+--------------+----------+
121 rows in set (0.00 sec)In this example, here is the order of execution:
- First, use
GROUP BYclause to group all rows bylast_namecolumn values. - Second, use the aggregate function
COUNT(*)to count rows in each group. - Finally, use
ORDER BYclause to sortCOUNT(*)column in descending order.
In this way, the last name KILMER with the largest number is ranked first.
GROUP BY, LIMIT, aggregate function
In this example, let us find the top 10 customers from the payment table. We will use GROUP BY clause, LIMIT clause and aggregate functions SUM().
SELECT customer_id, SUM(amount) total
FROM payment
GROUP BY customer_id
ORDER BY total DESC
LIMIT 10;
+-------------+--------+
| customer_id | total |
+-------------+--------+
| 526 | 221.55 |
| 148 | 216.54 |
| 144 | 195.58 |
| 137 | 194.61 |
| 178 | 194.61 |
| 459 | 186.62 |
| 469 | 177.60 |
| 468 | 175.61 |
| 236 | 175.58 |
| 181 | 174.66 |
+-------------+--------+
10 rows in set (0.02 sec)In this example, here is the order of execution:
- First, use
GROUP BYclause to group all rows bycustomer_idcolumn values. - Second, use the aggregate function
SUM(amount)to sumamountcolumns in each group, and give it a aliastotal; - Third, use
ORDER BYclause to sorttotalcolumn in descending order. - Finally, use the
LIMIT 10clause to return the top 10 rows.
The LIMIT applies to the whole result, not to each group. To return the top N rows separately for every category or other group, see How to Get the Top N Rows per Group in MySQL.
Examples of GROUP BY and HAVING
For a detailed guide to filtering grouped results, see MySQL HAVING.
You can use HAVING clause after GROUP BY clause to filter grouped rows. This statement returns customers whose total is more than 180.
SELECT customer_id, SUM(amount) total
FROM payment
GROUP BY customer_id
HAVING total > 180
ORDER BY total DESC;
+-------------+--------+
| customer_id | total |
+-------------+--------+
| 526 | 221.55 |
| 148 | 216.54 |
| 144 | 195.58 |
| 137 | 194.61 |
| 178 | 194.61 |
| 459 | 186.62 |
+-------------+--------+
6 rows in set (0.02 sec)In this example, here is the order of execution:
- First, use
GROUP BYclause to group all rows bycustomer_idcolumn values. - Second, use aggregate function
SUM(amount)to sumamountcolumns in each group, and give it a aliastotal; - Third, use
HAVINGclause to filtering rows whichtotalcolumn value is more than 180. - Finally, use
ORDER BYclause to sorttotalcolumn in descending order.
Conclusion
In this article, you learned MySQL GROUP BY syntax and use cases. The following are key points of the GROUP BY clause:
- The
GROUP BYclause is used to group some rows by specified columns or expressions. - The
HAVINGclause is used to filter grouped rows. - The
GROUP BYclause is often used for summarization with aggregate functions.