Top SQL Server Aggregate Functions Explained with Examples

← Prev

Whether you're just starting out with SQL or you're an experienced developer looking to sharpen your query skills, understanding aggregate functions is essential. These powerful tools allow you to summarize, analyze, and extract meaningful insights from your data, making them a cornerstone of effective database management.

In this guide, I'll walk through the most commonly used aggregate functions in SQL Server, such as SUM(), COUNT(), AVG(), MIN(), and MAX(). Each function is explained with clear, easy to understand examples so you can see exactly how they work in real world scenarios. Whether you're writing reports, building dashboards, or optimizing queries, mastering these functions will help you write cleaner, faster, and more efficient SQL code.

👉 Throughout this tutorial, I'll use the Books table as a sample dataset to test and illustrate how SQL Server aggregate functions work.

Sample Books table in SQL Server

1) COUNT() Function

The COUNT() function is one of the most commonly used aggregate functions in SQL Server. It retuns the number of rows that match a particular (or specified) condition or expression.

Syntax

COUNT(expression)

expression: This can be a column name, *, or any valid SQL expression.

Example 1.

SELECT COUNT(*) AS TotalBooks FROM dbo.Books  -- Output: 9

It returns the total number of rows in the table.

Example 2.

In the second example, the COUNT(Price) returns the count of rows where "price" is not null.

SELECT COUNT(Price) AS PricedBooks
FROM dbo.Books      -- Possible Output: 9

Example 3. This query will return the count of Distinct categories.

SELECT COUNT(DISTINCT Category) AS UniqueCategories
FROM dbo.Books  -- Output: 4

Example 4. Count with GROUP BY, will count how many books exist in each category.

SELECT Category, COUNT(*) AS BooksPerCategory
FROM dbo.Books
GROUP BY Category 

COUNT() function in SQL Server

2) SUM() Function

The SUM() function in SQL Server is an aggregate function used to calculate the total (sum) of numeric values in a column. It's commonly used in reporting, analytics, and data summaries.

Syntax

SUM(expression)

expression: A numeric column or calculation you want to total.
• It ignores NULL values automatically.
• The SUM() function must be used with GROUP BY clause if you are aggregating by categories or groups.

Example 1. Get the total of all prices in the Books table.

SELECT SUM(Price) AS TotalPrice
FROM dbo.Books     -- Output: 1153.55

Example 2. Using GROUP BY clause: This calculates the total price of books per category.

SELECT Category, SUM(Price) AS TotalPrice
FROM dbo.Books
GROUP BY Category

COUNT() Function Example

Example 3. With WHERE Clause: This totals only the prices of books in specified category.

SELECT SUM(Price) AS BooksTotal
FROM dbo.Books
WHERE Category IN ('Programming', 'Computers')

Example 4. With HAVING Clause: This returns only those categories where the total price exceeds 500.

SELECT Category, SUM(Price) AS TotalPrice
FROM dbo.Books
GROUP BY Category
HAVING SUM(Price) > 500

3) AVG() Function

The AVG() function is an aggregate function in SQL Server that calculates the average (mean) of a set of numeric values. It’s commonly used to analyze trends, performance, and pricing across datasets.

Syntax

AGV(expression)

expression: A numeric column or calculation whose average you want to compute.
• It ignores NULL values automatically.
• Must be used with GROUP BY if you're calculating averages per group.

Example 1. Get the average price of all Books.

SELECT AVG(Price) AS AveragePrice
FROM dbo.Books

Example 2. Calculate the average price of books per Category.

SELECT Category, AVG(Price) AS AveragePrice
FROM dbo.Books
GROUP BY Category

Example 3. With WHERE Clause: Calculate the average price of books that cost more than 200.

SELECT AVG(Price) AS HighAverage
FROM dbo.Books
WHERE Price > 200

4) MIN() Function

The MIN() function is an aggregate function in SQL Server that returns the smallest (minimum) value in a set of numeric, date, or string values. It’s useful for identifying the lowest price, earliest date, or alphabetically first item in a dataset.

Syntax

MIN(expression)

expression: A column or calculation whose minimum value you want to find.
• It ignores NULL values automatically.
• Must be used with GROUP BY if you're calculating averages per group.

Example 1. Get the "minimum" price among all books in the Books table.

SELECT MIN(Price) AS LowestPrice
FROM dbo.Books

Example 2. With WHERE Clause: Get the lowest price among books that cost more than 100.

SELECT MIN(Price) AS CheapestPremiumBook
FROM dbo.Books
WHERE Price > 100

Example 3. Using MIN() Function with Variable: You can use the MIN() function with a variable in SQL Server like this:

-- 1.
DECLARE @LowestPrice DECIMAL(10,2);
SELECT @LowestPrice = MIN(Price) 
    FROM dbo.Books;
SELECT @LowestPrice AS LowestBookPrice

-- 2.
DECLARE @LowestPrice DECIMAL(10,2);
SELECT @LowestPrice = MIN(Price) 
	FROM dbo.Books;
SELECT @LowestPrice

-- 3. Using a table variable to store multiple values and get the minimum value.
DECLARE @LowestPrice TABLE (PRICE DECIMAL(10,2));
INSERT INTO @LowestPrice VALUES (10.5), (120.75), (30);
SELECT MIN(Price) FROM @LowestPrice

5) MAX() Function

The MAX() function is an aggregate function in SQL Server that returns the largest (maximum) value from a set of values. It works with numeric, date/time, and string data types, making it versatile for many real-world scenarios.

Syntax

MAX(expression)

expression: A column or calculation whose maximum value you want to find.
• It ignores NULL values automatically.
• Can be used with GROUP BY to find maximums per group.

Example 1. Find the most expensive book in the dbo.Books table.

SELECT MAX(Price) AS HighestPrice
FROM dbo.Books

Example 2. Find the Longest Book Title (Alphabetically Last)

SELECT MAX(BookName) AS LastAlphabeticalTitle
FROM dbo.Books  -- Teaching Science

6) COUNT(DISTINCT) Function

The COUNT(DISTINCT) function is an aggregate function that returns the number of unique non-NULL values in a column. It’s especially useful when you want to eliminate duplicates from your count.

Syntax

COUNT(DISTINCT expression)

expression: A column or calculation whose distinct values you want to count.
• It ignores NULL values automatically.
• Cannot be used with multiple columns directly (only one expression allowed).

Example 1. Count the number of distinct categories in the Books table.

SELECT COUNT(DISTINCT Category) AS UniqueCategories
FROM dbo.Books

Example 2. Counts how many different categories in the price range 100 and 150.

SELECT COUNT(DISTINCT Category) AS UniqueCategory
FROM dbo.Books
WHERE Price >= 100 and Price <= 150

👉 Remember, there's a difference between COUNT() and COUNT(DISTINC) function

COUNT(Column): Counts all non-NULL values, including duplicates.
COUNT(DISTINCT Column): Counts only unique non-NULL values, ignoring duplicates.

For example,

SELECT COUNT(Category) AS TotalCategories,
       COUNT(DISTINCT Category) AS UniqueCategories
FROM dbo.Books  -- Output: TotalCategories - 9, UniqueCategories - 4

7) CHECKSUM_AGG() Function

CHECKSUM_AGG() is an aggregate function that returns a checksum value for a group of rows. It computes a single integer that represents all the values in a column (or expression).

It is often used to "detect" changes in a table or dataset. It can also be used to quickly compare whether two rows are identical.

Syntax

CHECKSUM_AGG(DISTINCT expression)

expression: Colomn name or expression to aggregate.
DISTINCT: Removes duplicates before computing checksum. This is optional.

Example 1. Basic checksum of a column.

Note: The column used with the CHECKSUM_AGG() function must be of an integer data type. Since the books table from the previous examples doesn't contain any integer columns, let's create a new table named sales for demonstration purposes.

CREATE TABLE Sales (
    SaleID INT,
    Amount INT
);

Now, insert few rows in the table.

INSERT INTO dbo.Sales (SaleID, Amount) values (1, 200)
INSERT INTO dbo.Sales (SaleID, Amount) values (2, 600)
INSERT INTO dbo.Sales (SaleID, Amount) values (3, 180)
INSERT INTO dbo.Sales (SaleID, Amount) values (4, 200)

Using CHECKSUM_AGG() on the "amount" column.

SELECT CHECKSUM_AGG(Amount) AS AmountChecksum
FROM Sales  
    -- Output: AmountChecksum - 748

Example 2. Using DISTINCT

SELECT CHECKSUM_AGG(DISTINCT Amount) AS DistinctAmountChecksum
FROM Sales;
    -- Output: AmountChecksum - 548

What exactly does these queries do? Is it useful in real-world scenarios?

👉 First, see the output of both the queries. Did you find any difference? Let me explain.

See the data that I have inserted in the "Sales" table again. The first and last row amount is same. The sales table amounts are.

200
600
180
200

Therefore, the first query resulted in - total amount: 748.
However, DISTINCT amount becomes,

200
600
180

So, the total amount is: 548

A checksum is an integer that represents a set of values. It does not show the values themselves, but it creates a numeric signature for them.

🤔 Is CHECKSUM_AGG() function useful?

Yes, it is useful for quick change detection. Suppose, you compute a checksum now, store it, and compute it again later.

If someone inserts, deletes, or updates an amount, the "checksum" changes.

This is faster than comparing row by row.

8) GROUPING() Function

The GROUPING() function in SQL Server is a bitwise function used with GROUP BY and GROUPING SETS, ROLLUP and CUBE to indicate whether a column in the resultset is aggregated (or rolled up) or represents an actual group value.

It returns 0 or 1.

0: The column is part of the grouped result or NOT aggregated.
1: The column is aggregated.

Syntax

GROUPING ( column_name )

GROUPING() can only be used inside SELECT when using GROUP BY ROLLUP, GROUP BY CUBE and GROUPING SETS.

Example 1: Using GROUPING() with ROLLUP

For this example, I am using the db.books table.

SELECT Category, 
    COUNT(*) AS TotalBooks, 
    GROUPING(Category) AS CategoryTotal 
FROM dbo.Books 
GROUP BY ROLLUP(Category)

Result:

SQL Server GROUPING() function with ROLLUP

Note: The NULL values appear in the last row because of the ROLLUP operation. These NULLs do not mean missing data, they mean, "This row is a rolled-up total, so this column has no specific value."

Example 2: Replace ROLLUP NULLs with Labels

In the example, I am using the db.Employee table.

SELECT
    CASE WHEN GROUPING(Department) = 1 THEN 'All Departments' 
         ELSE Department END AS Department,
    CASE WHEN GROUPING(YEAR(JoiningDate)) = 1 THEN 'All Years'
         ELSE CAST(YEAR(JoiningDate) AS VARCHAR(4)) END AS HireYear,
    COUNT(*) AS TotalEmployees
FROM Employee
GROUP BY ROLLUP (Department, YEAR(JoiningDate));

SQL Server GROUPING() function with ROLLUP

← Previous