AVG (Transact-SQL)
适用于: SQL Server Azure SQL 数据库 Azure SQL 托管实例 Azure Synapse Analytics 分析平台系统 (PDW) Microsoft Fabric 中的 SQL 分析端点 Microsoft Fabric 中的仓库
此函数返回组中各值的平均值。 将忽略 null 值。
语法
AVG ( [ ALL | DISTINCT ] expression )
[ OVER ( [ partition_by_clause ] order_by_clause ) ]
参数
ALL
向所有值应用此聚合函数。 ALL 为默认值。
DISTINCT
指定 AVG 只在每个值的唯一实例上执行,而不管该值出现了多少次。
expression
精确数值或近似数值数据类型类别(bit 数据类型除外)的表达式。 不允许聚合函数和子查询。
OVER ( [ partition_by_clause ] order_by_clause )
partition_by_clause 将 FROM 子句生成的结果集划分为要应用函数的分区 。 如果未指定,则此函数将查询结果集的所有行视为单个组。 order_by_clause 确定执行操作的逻辑顺序。 需要 order_by_clause 。 有关详细信息,请参阅 OVER 子句 (Transact-SQL)。
返回类型
expression 的计算结果确定返回类型。
表达式结果 | 返回类型 |
---|---|
tinyint | int |
smallint | int |
int | int |
bigint | bigint |
decimal 类别 (p, s) | decimal(38, max(s,6)) |
money 和 smallmoney 类别 | money |
float 和 real 类别 | float |
注解
如果 expression 的数据类型是别名数据类型,则返回类型也具有别名数据类型。 但是,如果提升别名数据类型的基本数据类型(例如从 tinyint 升级到 int),则返回值采用提升的数据类型,而不是别名数据类型。
AVG () 通过将这些值的总和除以非 null 值的计数来计算一组值的平均值。 如果总和超过返回值的数据类型的最大值,AVG() 将返回错误。
AVG 不与 OVER 和 ORDER BY 子句配合使用时为确定性函数。 使用 OVER 和 ORDER BY 子句指定时,这是不确定的。 有关详细信息,请参阅 Deterministic and Nondeterministic Functions。 此外,当将 AVG 与 float 和 real 数据类型一起使用时,AVG 可能显示为不确定的函数。 但根本原因是这些数据类型的大致性质。
示例
A. 使用 SUM 和 AVG 函数进行计算
以下示例计算 Adventure Works Cycles 的副总裁所用的平均休假小时数以及总的病假小时数。 对检索到的所有行,每个聚合函数都生成一个单独的汇总值。 该示例使用 AdventureWorks2022 数据库。
SELECT AVG(VacationHours)AS 'Average vacation hours',
SUM(SickLeaveHours) AS 'Total sick leave hours'
FROM HumanResources.Employee
WHERE JobTitle LIKE 'Vice President%';
结果集如下。
Average vacation hours Total sick leave hours
---------------------- ----------------------
25 97
(1 row(s) affected)
B. 搭配 GROUP BY 子句使用 SUM 和 AVG 函数
当与 GROUP BY
子句一起使用时,每个聚合函数都会针对每一组生成一个值,而不是针对整个表生成一个值。 以下示例针对 AdventureWorks2022 数据库中的每个销售地区生成汇总值。 汇总中列出每个地区的销售人员得到的平均奖金以及每个地区的本年度销售总额。
SELECT TerritoryID, AVG(Bonus)as 'Average bonus', SUM(SalesYTD) as 'YTD sales'
FROM Sales.SalesPerson
GROUP BY TerritoryID;
GO
结果集如下。
TerritoryID Average Bonus YTD Sales
----------- --------------------- ---------------------
NULL 0.00 1252127.9471
1 4133.3333 4502152.2674
2 4100.00 3763178.1787
3 2500.00 3189418.3662
4 2775.00 6709904.1666
5 6700.00 2315185.611
6 2750.00 4058260.1825
7 985.00 3121616.3202
8 75.00 1827066.7118
9 5650.00 1421810.9242
10 5150.00 4116871.2277
(11 row(s) affected)
°C 带 DISTINCT 使用 AVG
此语句返回 AdventureWorks2022 数据库中产品的平均标价。 通过使用 DISTINCT,计算仅考虑唯一值。
SELECT AVG(DISTINCT ListPrice)
FROM Production.Product;
结果集如下。
------------------------------
437.4042
(1 row(s) affected)
D. 不带 DISTINCT 使用 AVG
如果不使用 DISTINCT,AVG
函数将计算出 AdventureWorks2022 数据库的 Product
表中所有产品的平均标价,包括任何重复值。
SELECT AVG(ListPrice)
FROM Production.Product;
结果集如下。
------------------------------
438.6662
(1 row(s) affected)
E. 使用 OVER 子句
以下示例将 AVG 函数与 OVER 子句结合使用,以便为 AdventureWorks2022 数据库的 Sales.SalesPerson
表中的每个地区提供年度销售额的移动平均值。 数据按 TerritoryID
分区并在逻辑上按 SalesYTD
排序。 这意味着,将基于年度销售额为各区域计算 AVG 函数。 对于 TerritoryID
1,2005 年销售额有两行,表示当年销售额为两位销售人员。 将计算这两行的平均销售额,然后在计算中包括表示 2006 年销售额的第三行。
SELECT BusinessEntityID, TerritoryID
,DATEPART(yy,ModifiedDate) AS SalesYear
,CONVERT(VARCHAR(20),SalesYTD,1) AS SalesYTD
,CONVERT(VARCHAR(20),AVG(SalesYTD) OVER (PARTITION BY TerritoryID
ORDER BY DATEPART(yy,ModifiedDate)
),1) AS MovingAvg
,CONVERT(VARCHAR(20),SUM(SalesYTD) OVER (PARTITION BY TerritoryID
ORDER BY DATEPART(yy,ModifiedDate)
),1) AS CumulativeTotal
FROM Sales.SalesPerson
WHERE TerritoryID IS NULL OR TerritoryID < 5
ORDER BY TerritoryID,SalesYear;
结果集如下。
BusinessEntityID TerritoryID SalesYear SalesYTD MovingAvg CumulativeTotal
---------------- ----------- ----------- -------------------- -------------------- --------------------
274 NULL 2005 559,697.56 559,697.56 559,697.56
287 NULL 2006 519,905.93 539,801.75 1,079,603.50
285 NULL 2007 172,524.45 417,375.98 1,252,127.95
283 1 2005 1,573,012.94 1,462,795.04 2,925,590.07
280 1 2005 1,352,577.13 1,462,795.04 2,925,590.07
284 1 2006 1,576,562.20 1,500,717.42 4,502,152.27
275 2 2005 3,763,178.18 3,763,178.18 3,763,178.18
277 3 2005 3,189,418.37 3,189,418.37 3,189,418.37
276 4 2005 4,251,368.55 3,354,952.08 6,709,904.17
281 4 2005 2,458,535.62 3,354,952.08 6,709,904.17
(10 row(s) affected)
在此示例中,OVER 子句不包括 PARTITION BY。 这意味着该函数适用于查询返回的所有行。 在 OVER 子句中指定的 ORDER BY 子句将确定应用 AVG 函数的逻辑顺序。 该查询将按年为在 WHERE 子句中指定的所有销售区域返回销售额的移动平均值。 在 SELECT 语句中指定的 ORDER BY 子句将确定 SELECT 语句显示查询行的顺序。
SELECT BusinessEntityID, TerritoryID
,DATEPART(yy,ModifiedDate) AS SalesYear
,CONVERT(VARCHAR(20),SalesYTD,1) AS SalesYTD
,CONVERT(VARCHAR(20),AVG(SalesYTD) OVER (ORDER BY DATEPART(yy,ModifiedDate)
),1) AS MovingAvg
,CONVERT(VARCHAR(20),SUM(SalesYTD) OVER (ORDER BY DATEPART(yy,ModifiedDate)
),1) AS CumulativeTotal
FROM Sales.SalesPerson
WHERE TerritoryID IS NULL OR TerritoryID < 5
ORDER BY SalesYear;
结果集如下。
BusinessEntityID TerritoryID SalesYear SalesYTD MovingAvg CumulativeTotal
---------------- ----------- ----------- -------------------- -------------------- --------------------
274 NULL 2005 559,697.56 2,449,684.05 17,147,788.35
275 2 2005 3,763,178.18 2,449,684.05 17,147,788.35
276 4 2005 4,251,368.55 2,449,684.05 17,147,788.35
277 3 2005 3,189,418.37 2,449,684.05 17,147,788.35
280 1 2005 1,352,577.13 2,449,684.05 17,147,788.35
281 4 2005 2,458,535.62 2,449,684.05 17,147,788.35
283 1 2005 1,573,012.94 2,449,684.05 17,147,788.35
284 1 2006 1,576,562.20 2,138,250.72 19,244,256.47
287 NULL 2006 519,905.93 2,138,250.72 19,244,256.47
285 NULL 2007 172,524.45 1,941,678.09 19,416,780.93
(10 row(s) affected)