GROUP BY is a popular SQL command that organizes identical rows (those with the same values in certain columns) into groups. This command is particularly useful for grouping and sorting data in large databases. Typically, GROUP BY is used with aggregate functions to perform operations on each group of data.
This article will focus on the GROUP BY usage in various scenarios and use cases.
Understanding GROUP BY in SQL Server
The purpose of the GROUP BY command is to group records with identical values and help with data aggregation by working in conjunction with the SQL aggregate functions. This way, it allows you to retrieve the aggregate function results for each group.
The basic syntax of a query with GROUP BY is:
SELECT Column_Name, Function_Name
FROM Table_Name
WHERE Condition
GROUP BY Column_Name
Parameters:
Column_Name is the name of the column(s) for which you want to group rows with identical values
Function_Name is the aggregate function (COUNT(), MIN(), MAX(), SUM(), or AVG())
Table_Name is the name of the table to obtain data from
Condition is the statement used to filter output data
Note
GROUP BY must be placed after the WHERE clause (if that clause is present) and before the HAVING clause (if that clause is used in a query).
Assume we want to count the number of employees according to their job titles (to illustrate the use cases in this article, we utilize the AdventureWorks2022 test database and dbForge Studio for SQL Server, a robust IDE for SQL Server databases).
SELECT JobTitle,COUNT(*) AS NumberOfEmployees
FROM HumanResources.Employee
WHERE CurrentFlag = 1
GROUP BY JobTitle
Now, let us explore various scenarios of using GROUP BY in practice.
GROUP BY with aggregate functions
Data aggregation is a crucial task in data management, and the SQL GROUP BY clause is an effective tool for improving the efficiency of such tasks. By using GROUP BY, we can organize query results more effectively and apply aggregate functions like COUNT(), SUM(), MAX(), MIN(), and AVG() to deliver summarized data. The GROUP BY clause groups the data, and aggregate functions provide summaries for each group.
For example, to count the total orders, calculate the total sales, and determine the average sales values for each year, we can use the following SQL query with GROUP BY and the aggregate functions COUNT(), SUM(), and AVG():
SELECT
YEAR(OrderDate) AS OrderYear,
COUNT(*) AS TotalOrders,
SUM(TotalDue) AS TotalSales,
AVG(TotalDue) AS AverageSales
FROM
Sales.SalesOrderHeader
GROUP BY
YEAR(OrderDate)
ORDER BY
OrderYear
GROUP BY with HAVING
In SQL, both the WHERE and HAVING clauses are used to filter records, but they serve different purposes when combined with the GROUP BY clause.
The WHERE clause filters records before the grouping stage. It limits the rows selected for aggregation and grouping and is used to specify conditions on individual rows.
On the other hand, the HAVING clause filters records after the grouping stage, limiting the results of the GROUP BY operation. It is used to specify conditions on aggregate functions (which WHERE cannot do) or the overall grouped data.
For example, if we want to find the years when total sales values exceeded $1,000,000, we use the HAVING clause to filter the results after grouping. The query would include the SUM() aggregate function as the filtering condition.
SELECT
YEAR(OrderDate) AS OrderYear,
COUNT(*) AS TotalOrders,
SUM(TotalDue) AS TotalSales
FROM
Sales.SalesOrderHeader
GROUP BY
YEAR(OrderDate)
HAVING
SUM(TotalDue) > 1000000
GROUP BY with JOIN
When working with multiple tables in the FROM clause, the JOIN clause allows us to combine results from different tables (or different columns from the same table). JOINs are highly effective when used with GROUP BY, enabling us to group results by any column from any table.
In the test case, we need to calculate the total sales and the total sales amount for each product. To achieve this, we need to reference the Sales.SalesOrderDetail table and the Production.Product table. We will use the JOIN clause to combine these tables and then apply the GROUP BY clause to group the results by product.
SELECT
P.Name AS ProductName,
SUM(SOD.OrderQty) AS TotalQuantitySold,
SUM(SOD.LineTotal) AS TotalSalesAmount
FROM
Sales.SalesOrderDetail SOD
JOIN
Production.Product P ON SOD.ProductID = P.ProductID
GROUP BY
P.Name
ORDER BY
TotalSalesAmount DESC
This query returns the total quantity sold and the total sales amount for each product, sorted by the total sales amount in descending order.
GROUP BY with ROLLUP
ROLLUP is an extension of the GROUP BY clause in SQL, used to generate subtotals and grand totals for data in a table. The GROUP BY ROLLUP feature groups data by one or multiple columns and calculates subtotals and grand totals for each group.
First, it calculates the aggregate values specified in the GROUP BY clause. Then it produces higher-level subtotals, "rolling up" from the most detailed level to the grand total level as defined in the ROLLUP clause.
The basic syntax of the query with GROUP BY ROLLUP is:
SELECT Column_Name, Function_Name(column)
FROM Table_Name
GROUP BY ROLLUP (Column_Name)
Parameters:
Column_Name is the name of the column(s) for grouping data
Function_Name(column) is an optional aggregation function for performing calculations on the grouped data
Table_Name is the name of the table to obtain data from
GROUP BY is the clause specifying the column or columns to group by for the aggregate operation
ROLLUP creates multiple groups (i.e., grouping sets) and applies the aggregate function hierarchically when combined with GROUP BY
In the test case, we want to summarize the total sales amount by year and quarter, with subtotals for each year and a grand total. The query is as follows:
SELECT
COALESCE(CAST(YEAR(OrderDate) AS VARCHAR), 'All Years') AS Year,
COALESCE(CAST(DATEPART(QUARTER, OrderDate) AS VARCHAR), 'All Quarters') AS Quarter,
SUM(TotalDue) AS TotalSales
FROM
Sales.SalesOrderHeader
GROUP BY
ROLLUP(YEAR(OrderDate), DATEPART(QUARTER, OrderDate))
ORDER BY
GROUPING(YEAR(OrderDate)),
YEAR(OrderDate),
GROUPING(DATEPART(QUARTER, OrderDate)),
DATEPART(QUARTER, OrderDate)
This query selects the year and quarter from the OrderDate, calculates the sum of TotalDue for each year and quarter, and uses
GROUP BY ROLLUP to create subtotals for each year and a grand total for all years. We also order the results by year and quarter for better readability.
This feature is exceptionally useful for analyzing data at different levels of detail. It eliminates the need to write and execute separate queries for calculating subtotals and totals, allowing users to obtain results faster and more efficiently.
GROUP BY with multiple columns
Using GROUP BY with multiple columns allows you to group rows with identical values in specified columns, which is useful for generating statistics for various combinations of columns. The system creates a unique group for each unique combination of values in the specified columns.
Assume we want to analyze the total sales by each employee for each year. The query is:
SELECT
e.BusinessEntityID AS EmployeeID,
p.FirstName + ' ' + p.LastName AS EmployeeName,
YEAR(soh.OrderDate) AS Year,
SUM(soh.TotalDue) AS TotalSales
FROM
Sales.SalesOrderHeader AS soh
JOIN
Sales.SalesPerson AS sp ON soh.SalesPersonID = sp.BusinessEntityID
JOIN
HumanResources.Employee AS e ON sp.BusinessEntityID = e.BusinessEntityID
JOIN
Person.Person AS p ON e.BusinessEntityID = p.BusinessEntityID
GROUP BY
e.BusinessEntityID,
p.FirstName,
p.LastName,
YEAR(soh.OrderDate)
ORDER BY
e.BusinessEntityID,
YEAR(soh.OrderDate)
This query selects the data from several tables in AdventureWorks2022 using the JOIN clause and calculates the total sales amount for each employee and year. The GROUP BY clause groups the rows by unique combinations of employee ID, employee name, and year.
Try it yourself with dbForge Studio
All test cases discussed in this article used dbForge Studio for SQL Server, which allowed us to write and execute queries directly against the AdventureWorks2022 database.
By automatically suggesting and adding non-aggregated columns to the GROUP BY clause, the T-SQL Editor in the Studio saves time and effort for SQL developers. Moreover, it allows you to reduce errors in the GROUP BY clause by intelligently identifying and including relevant columns based on the query context. The ability to insert multiple list items with a single click makes the query writing process more efficient and intuitive.
T-SQL Editor covers different SQL dialects and provider-specific rules regarding aliases in the GROUP BY clause, ensuring compatibility and flexibility across various database platforms.
The output, presented in a user-friendly table format, is convenient for further analysis. The data can be easily exported into various formats.
dbForge Studio for SQL Server is a much more powerful alternative to SSMS (the default SQL Server Management Studio), containing lots of tools that you won't find in SSMS. A comprehensive toolset covers all database-related tasks in SQL Server, such as T-SQL coding, database comparison, synchronization and changes deployment, data import and export, source control, and much more.
Conclusion
Data management relies heavily on various grouping, sorting, and filtering operations, and SQL provides powerful tools for these tasks, such as the GROUP BY clause. This clause is used with aggregate functions, JOINs, condition-specifying clauses, and the ROLLUP operator, enabling users to quickly obtain necessary data, grouped and ordered for better business decisions.
To effectively work with the GROUP BY clause and T-SQL in its full range of interactions with SQL Server databases, you need highly functional and efficient tools like dbForge Studio for SQL Server. Download the 30-day FREE trial, install the software, get familiar with its functionality, and evaluate it under the full workload!
Try dbForge Studio for SQL Server and speed up your database tasks!
Try now
Studio for SQL Server
All-in-one tool for developing, managing, and maintaining SQL Server databases
We use cookies to provide you with a better experience on the Devart website. You can read more about our use of cookies in our Cookies Policy.
Click OK to continue browsing the Devart site. Be aware you can disable cookies at any time.