This SQL tutorial focuses on the MySQL Group By Clause, and provides explanations, examples and exercises. For this lesson’s exercises use this link.

This tutorial is a part of several posts explaining how to use the MySQL Group Functions. To read additional posts regarding this subject, please use the following links:

 

 


The MySQL GROUP BY Clause

SELECT       column_name , group_function(column_name)
FROM         table_name
WHERE        condition
GROUP BY     column_name

So far, each group function described in the previous tutorial has treated the table as one large group of data. In most cases you need to divide the table into smaller groups, instead of getting the average price of all books in Books table, you would rather see, for example, the average price grouped by each category (what is the average price of the “Fiction” category, “Travel” category and so on).

You can use the MySQL GROUP BY clause to divide the rows in a table into groups. Then you can use the group functions to retrieve summary information for each group.

This MySQL example would retrieve a summary of the average price for each category number:

SELECT      category_id , AVG(price)
FROM        books
GROUP BY    category_id

 

A Few Guidelines

All columns in the MySQL SELECT clause that are not group functions must be in the GROUP BY clause

When specifying group functions (such as AVG) in the SELECT clause, alongside with other individual items (such as category_id), you must include a GROUP BY clause. In the GROUP BY clause you must specify these individual items (category_id in this case).

oracle_group_by

Note: If an individual column (such as category_id) is not specified at the GROUP BY clause, The server is free to choose any value from this column to display alongside every group. This is an extension of the standard SQL (in Oracle or Microsoft this kind of action would result an error), and could be useful when all values of the individual column are the same for each group.

The MySQL GROUP BY columns don’t have to be in the MySQL SELECT clause

It is absolutely possible to group by different columns, but not to specify these columns in the MySQL SELECT clause (however the result will not be meaningful). This MySQL example would retrieve a summary of the average price for each category without displaying the respective category numbers.

SELECT      AVG(price)
FROM        books
GROUP BY    category_id

 

You can list more than one column after the MySQL GROUP BY clause

Sometimes you need to see the result for groups within groups, for example: each category is provided by different publishers (“Fiction” books are provided by 4 different publishers). While the MySQL examples carried out so far were meant to display the average of each category, the query specified below retrieves a summary of the average price for each category and for each publisher:

SELECT      category_id , publisher_id , AVG(price)
FROM        books
GROUP BY    category_id , publisher_id

 

Using the MySQL WHERE clause, you can exclude rows before dividing them into groups.

For example, if you need to display the average price only for categories 50, 80, and 90:

SELECT      category_id , AVG(price)
FROM        books
WHERE       category_id IN (50, 80, 90)
GROUP BY    category_id

 

You cannot use the MySQL WHERE clause to restrict groups

As seen in the last example, using the MySQL WHERE clause you can restrict rows before dividing them into groups. However, it is not possible to specify group functions in a MySQL WHERE clause, as that would result in an error.

The categories where the average price is higher than 50:

 SELECT      category_id , AVG(price)
 FROM        books
 WHERE       AVG(price) > 50
 GROUP BY    category_id    

-- (error)