Preamble
Using the GROUP BY operator, the SELECT operator in SQL Server can get information from multiple records and group the results by one or more columns.
Syntax of GROUP BY statement in SQL
SELECT expr1, expr2, … expr_n,
aggregate_function (aggregate_expr)
FROM tab
[WHERE conds]
GROUP BY expr1, expr2, … expr_n
[ORDER BY expr [ ASC | DESC ]];
where:
- expr1,2, …_n – Expressions that are not encapsulated in the aggregate function and must be included in GROUP BY at the end of the SQL query.
- aggr_function – This is an aggregate function such as SUM, COUNT, MIN, MAX or AVG.
- aggr_expression – This is the column or expression for which aggregate_function will be used.
- tab – The tables from which you want the records. The FROM sentence must contain at least one table.
- WHERE conds – It’s optional. The prerequisites for choosing records are as follows.
- ORDER BY – It’s optional. The expression used to order the records in the result set; multiple expressions must be specified, with commas separating the values.
- ASC – It’s optional. ASC sorts the result set in ascending order by. This is the default behavior if no modifier is specified.
- DESC – It’s optional. DESC sorts the result set in descending order.
Using GROUP BY with SUM function
Let’s examine how to employ SQL’s GROUP BY with SUM function.
In this illustration, we have a table with the information below:
| emp_number | f_name | l_name | sal | dept |
| 1001 | Justin | Bieber | 62000 | 500 |
| 1002 | Selena | Gomez | 57500 | 500 |
| 1003 | Mila | Kunis | 71000 | 501 |
| 1004 | Tom | Cruise | 42000 | 501 |
Put the following SQL query here:
SELECT dept,
SUM(salary) AS total_sal
FROM employees
GROUP BY dept;
There will be two records chosen. These are the outcomes you’ll get:
| dept | total_sal |
| 500 | 119500 |
| 501 | 113000 |
In this example, all of the salaries for each department were added using the SUM function, and the resulting value was given the moniker “total_sal.” Since dept is not contained within the SUM function, it needs to be specified in the GROUP BY clause.
Using GROUP BY with function COUNT
Let’s examine how to use SQL’s GROUP BY option with the COUNT function.
In this illustration, the product table contains the information below:
| prod_id | prod_name | cat_id |
| 1 | Pear | 50 |
| 2 | Banana | 50 |
| 3 | Orange | 50 |
| 4 | Apple | 50 |
| 5 | Bread | 75 |
| 6 | Sliced Ham | 25 |
| 7 | Kleenex | NULL |
Enter the following SQL statement:
SELECT cat_id,
COUNT(*) AS total_prod
FROM prod
WHERE cat_id IS NOT NULL
GROUP BY cat_id
ORDER BY cat_id;
We’ll pick three records. The outcomes that you should see are as follows:
| cat_id | total_prod |
| 25 | 1 |
| 50 | 4 |
| 75 | 1 |
In this example, the number of total_prod for each cat_id was determined using the COUNT function, and the result was specified as the alias “total_prod.” In the WHERE clause, we filtered out and excluded all cat_id values that have a value of NULL. Cat_id must be specified in the GROUP BY clause because it is not included in the COUNT function.
Using GROUP BY with function MIN
Let’s now examine how to use the SQL MIN function in conjunction with the GROUP BY option.
We’ll use the table with the following information once more in this illustration:
| emp_number | f_name | l_name | sal | dept |
| 1001 | Justin | Bieber | 62000 | 500 |
| 1002 | Selena | Gomez | 57500 | 500 |
| 1003 | Mila | Kunis | 71000 | 501 |
| 1004 | Tom | Cruise | 42000 | 501 |
Enter the following SQL statement:
SELECT dept,
MIN(sal) AS lowest_sal
FROM empl
GROUP BY dept;
There will be two records chosen. You will see the following results:
| dept | low_sal |
| 500 | 57500 |
| 501 | 42000 |
In this example, we used the MIN function to return the lowest pay for each department, and we gave the resulting values to the MIN function’s “low_sal” alias. Dept must be specified in the GROUP BY clause because it is not contained in the MIN function.
Using GROUP BY with the MAX function
Let’s now examine how to combine the MAX feature with the GROUP BY offer.
Reusing the employees table, let’s determine the highest pay for each dept_id this time:
| emp_number | f_name | l_name | sal | dept |
| 1001 | Justin | Bieber | 62000 | 500 |
| 1002 | Selena | Gomez | 57500 | 500 |
| 1003 | Mila | Kunis | 71000 | 501 |
| 1004 | Tom | Cruise | 42000 | 501 |
Enter the following SQL statement:
SELECT dept,
MAX(sal) AS highest_sal
FROM empl
GROUP BY dept;
Two records will be selected. Here are the results that you should get:
| dept | high_sal |
| 500 | 62000 |
| 501 | 71000 |
In this example, the MAX function was used to return the highest possible salary value for each department, and the output was given the alias “high_salary.” Since the dept column is not included in the MAX function, it must be specified in the GROUP BY clause.
More Examples:
All examples will be on this table unless otherwise stated:
| f_id | f_name | f_age | f_sal |
| 1 | Justin | 23 | 100 |
| 2 | Selena | 23 | 200 |
| 3 | Mila | 23 | 300 |
| 4 | Tom | 24 | 1000 |
| 5 | Christian | 24 | 2000 |
| 6 | Daniel | 25 | 1000 |
Example №1
The records in this example are divided into three age groups: 23 years, 24 years, and 25 years. The sum function is then used for each group, totaling the wages for that group.
In order to determine the total salaries for each of the groups (23, 24 and 25 years), the following formula will be used:
SELECT f_age, SUM(f_sal) as sum FROM workers_1 GROUP BY f_age
The SQL query will select the following lines:
| f_age | sum |
| 23 | 600 |
| 24 | 3000 |
| 25 | 1000 |
Example №2
In this illustration, we use the additional condition that we should not include all table entries:
SELECT f_age, SUM(f_sal) as sum FROM workers_1 WHERE id>=2 GROUP BY f_age
The SQL query will select the following lines:
| f_age | sum |
| 23 | 500 |
| 24 | 3000 |
| 25 | 1000 |
Example №3
The records in this example are divided into three age groups: 23 years, 24 years, and 25 years. The function max is then used for each group to determine the highest pay within that group:
SELECT f_age, MAX(f_sal) as max FROM workers_1 GROUP BY f_age
The SQL query will select the following lines:
| f_age | max sal |
| 23 | 300 |
| 24 | 2000 |
| 25 | 1000 |
Example №4
We can now use the min function to determine the minimum wage for this group:
SELECT f_age, MIN(f_sal) as min FROM workers_1 GROUP BY f_age
The SQL query will select the following lines:
| f_age | min sal |
| 23 | 100 |
| 24 | 1000 |
| 25 | 1000 |
Example №5
And now, with the help of the count function, you will find the number of records in the group:
SELECT f_age, COUNT(*) as count FROM workers_1 GROUP BY f_age
The following lines will be chosen by the SQL query:
| f_age | count |
| 23 | 3 |
| 24 | 2 |
| 25 | 1 |
Understanding the use of GROUP BY clause in SQL
About Enteros
Enteros offers a patented database performance management SaaS platform. It finds the root causes of complex database scalability and performance problems that affect business across a growing number of cloud, RDBMS, NoSQL, and machine learning database platforms.
The views expressed on this blog are those of the author and do not necessarily reflect the opinions of Enteros Inc. This blog may contain links to the content of third-party sites. By providing such links, Enteros Inc. does not adopt, guarantee, approve, or endorse the information, views, or products available on such sites.
Are you interested in writing for Enteros’ Blog? Please send us a pitch!
RELATED POSTS
How Can Enterprises Reduce Database Costs Without Sacrificing Performance?
- 11 September 2026
- Database Performance Management
Enterprises can reduce database costs without sacrificing performance by identifying inefficient SQL, right-sizing infrastructure, eliminating unused capacity, analyzing workload patterns, improving storage efficiency, and using database observability to connect resource consumption with application performance. Database cost optimization helps organizations control infrastructure spending while Enteros UpBeat provides performance intelligence, workload visibility, predictive analytics, and Cloud FinOps … Continue reading “How Can Enterprises Reduce Database Costs Without Sacrificing Performance?”
How Can AI Detect Database Performance Anomalies Before They Cause Downtime?
AI can detect database performance anomalies by continuously analyzing workload patterns, SQL behavior, latency, resource usage, waits, and historical baselines. AI database anomaly detection helps identify unusual behavior before it becomes a larger outage. With Enteros UpBeat, IT teams can detect emerging issues earlier, investigate root causes faster, and improve database reliability across complex enterprise … Continue reading “How Can AI Detect Database Performance Anomalies Before They Cause Downtime?”
How Can Financial Institutions Detect Database Bottlenecks Before Transaction Delays Occur?
- 10 September 2026
- Database Performance Management
Financial institutions can detect database bottlenecks before transaction delays occur by continuously monitoring query latency, database waits, CPU, memory, I/O, locking, workload changes, and transaction throughput. By combining performance baselines, anomaly detection, SQL intelligence, predictive analytics, and automated root cause analysis, teams can identify emerging issues early and optimize databases before customer-facing banking, payment, or … Continue reading “How Can Financial Institutions Detect Database Bottlenecks Before Transaction Delays Occur?”
What Role Does AI-Powered Database Monitoring for Banking Play in Performance Management?
AI-powered database monitoring for banking helps financial institutions detect anomalies, identify performance bottlenecks, analyse SQL workloads, predict capacity risks, and accelerate troubleshooting. By combining database observability with automated analysis, AI-powered database performance supports faster incident response, more reliable transactions, better resource utilisation, stronger capacity planning, and smarter cloud cost decisions across increasingly complex banking database … Continue reading “What Role Does AI-Powered Database Monitoring for Banking Play in Performance Management?”