Max, Min, and Avg SQL Server Functions


By:   |   Updated: 2016-08-23   |   Comments (1)   |   Related: More > Functions - System

Problem

How do I find some of the basic descriptive statistics of a column such as the maximum, minimum, and average values in SQL Server with T-SQL code?  Can you provide some examples?

Solution

SQL Server Max, Min and Avg Functions

SQL Server provides several built in functions to help get some basic data about a column of data.

  • Max returns the maximum value of the column. It does this using the collating sequence so it can work on character and datetime columns in addition to numeric ones.
  • Min is the inverse. It returns the smallest value of the column and also works with several different data types.
  • Avg returns the average or arithmetic mean of the values. It adds all non-null values in the column and then divides them by the number of values added to get the mean. Since it is adding and dividing, AVG requires the column or expression to have a numeric value, and the return type from AVG is determined by the type of the expression.

SQL Server Max, Min and Avg Function Examples

Examples can make these functions much easier to understand. So, let's start with an arbitrary table of some significant constants.

  create table constants (
  ConstName varchar(50) primary key,
  PrimaryField varchar(50),
  ApproxValue decimal(20, 10) )

  insert into dbo.constants (ConstName, PrimaryField, ApproxValue)
  values
  ('Pi', 'Geometry', '3.1415926535'),
  ('Euler''s Number e', 'Probability Theory', '2.71828'),
  ('Square Root of 2', 'Geometry', '1.41421'),
  ('Golden Ratio', 'Geometry', '1.618'),
  ('Twin Prime Constant', 'Number Theory', '0.66016'),
  ('Conway''s Constant', 'Number Theory', '1.30357')

In the most basic usage, we could get the max, min, and average values of these constants. Like this:

select
 max(ApproxValue) as MaxValue, avg(ApproxValue) as AvgValue, min(ApproxValue) as MinValue
from 
 dbo.constants

Basic Max, Avg, Min Functions in SQL Server

But this gives us the values for the entire table. If we want to get the values for a particular field of study, we would need to use a group by clause. Like:

select
 PrimaryField,
 max(ApproxValue) as MaxValue, avg(ApproxValue) as AvgValue, min(ApproxValue) as MinValue
from 
 dbo.constants
group by
 PrimaryField

Group by Max, Avg, Min in SQL Server

The Entire Row with SQL Server Min and Max Functions

When we looked at it with a group by clause, we got the descriptive values for the entire table, but it did not give us the row those values came from. So we did not have the name of the constants that had those maximum and minimum values. We can approach this by joining against a subquery. For instance:

select
 c1.PrimaryField, c1.ConstName, c1.ApproxValue
from 
 dbo.constants c1
 join (
  select PrimaryField, max(ApproxValue) ApproxValue 
  from dbo.constants
  group by PrimaryField) c2
 on c1.PrimaryField = c2.PrimaryField 
  and c1.ApproxValue = c2.ApproxValue

Max Subquery in SQL Server T-SQL Code

For each field of study this gives us the constant that has the greatest approximate value. In this example, there are no duplicated approximate values, but if the greatest approximate value for a field did appear in more than one row it would be returned twice. We could get the smallest values just by changing the max to min in the code above. This would not work with average of course since the actual average value does not exist in the table.

If we want to return the maximum and minimum constants and their names for a field in the same row, we need to be slightly more sophisticated, but we can use a common table expression or CTE to make it more readable.

; with MaxCTE as (
 select
  c1.PrimaryField, c1.ConstName, c1.ApproxValue
 from 
  dbo.constants c1
  join (
   select PrimaryField, max(ApproxValue) ApproxValue
   from dbo.constants
   group by PrimaryField) c2
  on c1.PrimaryField = c2.PrimaryField 
   and c1.ApproxValue = c2.ApproxValue ),

 minCTE as (
  select
   c1.PrimaryField, c1.ConstName, c1.ApproxValue
  from 
   dbo.constants c1
   join (
    select PrimaryField, min(ApproxValue) ApproxValue
    from dbo.constants
    group by PrimaryField) c2
   on c1.PrimaryField = c2.PrimaryField 
    and c1.ApproxValue = c2.ApproxValue )

select distinct
 c.PrimaryField, 
 maxCTE.ConstName as HighValueConstant, maxCTE.ApproxValue as HighValue,
 minCTE.ConstName as LowValueConstant, minCTE.ApproxValue as LowValue
from
 dbo.constants c
 join MaxCTE
  on c.PrimaryField = MaxCTE.PrimaryField
 join MinCTE
  on c.PrimaryField = minCte.PrimaryField
  and MaxCTE.PrimaryField = minCTE.PrimaryField;

CTE for Readability in SQL Server T-SQL Code

This will repeat rows if either a high value or a low value in field is duplicated, but that does not appear here.

Max, Min and Avg SQL Server Functions with Partitioning

Max, min, and avg all support partitioning. If we wanted to get the relevant values for each field with partitioning, using an over clause it would look like:

select distinct
 PrimaryField,
 max(ApproxValue) over (partition by PrimaryField) as HighestConstant,
 min(ApproxValue) over (partition by PrimaryField) as LowestConstant,
 avg(ApproxValue) over (partition by PrimaryField) as AvgValue
from
 dbo.constants

Max, Min and Avg SQL Server Functions with Partitioning
Next Steps
  • Count is another aggregate function that can help describe the data in a table.
  • Dalls Snider provides an overview of a related but more advanced technique for min-max column normalization.
  • Along with the average, the mode is another significant part of descriptive statistics. Koen Verbeeck provides a method to calculate the mode.


Last Updated: 2016-08-23


get scripts

next tip button



About the author
MSSQLTips author Tim Wiseman Tim Wiseman is a SQL Server DBA and Python Developer in Las Vegas.

View all my tips





Comments For This Article




Friday, May 08, 2020 - 8:14:52 PM - Javier Back To Top

Hi Tim,

Can you help me? I try to obtain a dynamical data but the min and max function not work with my syntax, avg and stdev works fine.

Example:

@hvp--- It´s the variable where save the quantity of decimals to put in the result

FORMAT(CAST(ROUND(MIN (N2),@hvp) as float), '0.###############') N2min, --- OUTPUT 1.32 ---- and the rest of decimals?

FORMAT(CAST(ROUND(MAX (N2),@hvp) as float), '0.###############') N2max,--- OUTPUT 1.4 ---- and the rest of decimals?

FORMAT(CAST(ROUND(AVG (N2),@hvp) as float), '0.###############') N2avg,--- OUTPUT 1.388888888888888 ---- This is Ok

FORMAT(CAST(ROUND(STDEV (N2),@hvp) as float), '0.###############') N2stdev,--- OUTPUT 1.377777777777777 ---- This is Ok



download


Recommended Reading

Concatenate SQL Server Columns into a String with CONCAT()

SQL Server Rounding Functions - Round, Ceiling and Floor

SQL Server 2016 STRING_SPLIT Function

Using FOR XML PATH and STRING_AGG() to denormalize SQL Server data

Different ways to get random data for SQL Server data sampling





get free sql tips
agree to terms


Learn more about SQL Server tools