Em SQL, o
AVG()
function é uma função agregada que retorna a média de todos os valores em uma determinada expressão. Ele também pode ser usado para retornar a média de todos os valores distintos (exclusivos) em uma expressão.
A expressão deve ser numérica (não pode ser cadeia de caracteres, cadeia de bits ou data e hora).
Abaixo estão alguns exemplos básicos para demonstrar como funciona.
Tabela de amostra
Suponha que temos a seguinte tabela:
SELECT * FROM Products;
Resultado:
+-------------+------------+------------------- --------------+----------------+------------------ -----------------------+| ProductId | ID do fornecedor | NomeDoProduto | Preço do produto | Descrição do produto ||-------------+------------+------ -------------+----------------+------------------- -----------------------|| 1 | 1001 | Chave de fenda para canhotos | 25,99 | Roxa. Inclui caixa de transporte para canhotos. || 2 | 1001 | Peso Longo (azul) | 14,75 | Inclui uma longa espera. || 3 | 1001 | Peso Longo (verde) | 11,99 | Tempo de espera aproximado de 30 minutos. || 4 | 1002 | Marreta | 33,49 | Cabo de madeira. Taças de vinho grátis. || 5 | 1003 | Motosserra | 245,00 | Laranja. Inclui dedos sobressalentes. || 6 | 1003 | Caixa de palha para cachorro | NULO | Amarrado com vinhas. Muito mastigável. || 7 | 1004 | Canecas de café sem fundo (pacote com 4) | 9,99 | Cerâmica marrom com cabo sólido. || 8 | 1001 | Chave de fenda destro | 25,99 | Azul. Inclui caixa de transporte para destros. |+-------------+------------+--------------------- ------------+----------------+-------------------- ----------+
Exemplo
Podemos usar a seguinte consulta para obter a média de todos os preços.
SELECT AVG(ProductPrice)
FROM Products;
Resultado:
+--------------------+| (Sem nome de coluna) ||--------------------|| 52.457142 |+--------------------+
Nesse caso, as informações de preço são armazenadas no
ProductPrice
coluna, e então passamos isso como um argumento para o AVG()
função, que então calcula a média e retorna o resultado. Usando aliases de coluna
Você notará que os resultados anteriores não incluem um nome de coluna. Isso é esperado, porque o
AVG()
A função não retorna nenhuma coluna. Você pode fornecer facilmente um nome de coluna atribuindo um alias. SELECT AVG(ProductPrice) AS Average
FROM Products;
Resultado:
+-----------+| Média ||-----------|| 52.457142 |+-----------+
Resultados filtrados
O
AVG()
A função opera nas linhas retornadas pela consulta. Portanto, se você filtrar os resultados, o resultado de AVG()
vai refletir isso. SELECT AVG(ProductPrice) AS Average
FROM Products
WHERE VendorId = 1001;
Resultado:
+-----------+| Média ||-----------|| 19.680000 |+-----------+
Nesse caso, 19,680000 é o preço médio de todos os produtos oferecidos pelo fornecedor especificado.
NULL
Valores
O
AVG()
função ignora qualquer NULL
valores. Em nossa tabela de amostra acima, número do produto 6
tem NULL
em seu ProductPrice
coluna, mas isso foi ignorado em nosso AVG()
exemplo. Dependendo de seu DBMS e suas configurações, você pode ou não ver um aviso de que
NULL
valores foram eliminados no conjunto de resultados. Aqui está um exemplo do que você pode ver:
SELECT AVG(ProductPrice) AS Average
FROM Products;
Resultado:
+-----------+| Média ||-----------|| 52.457142 |+-----------+Aviso:o valor nulo é eliminado por um agregado ou outra operação SET.
Tudo isso nos diz que a coluna continha pelo menos um
NULL
valor, e que foi ignorado no cálculo dos resultados. Dados de data/hora
O
AVG()
função não aceita expressões de data/hora. Suponha que temos a seguinte tabela:
SELECT PetName, DOB
FROM Pets;
Resultado:
+-----------+------------+| PetName | DOB ||-----------+------------|| Fofo | 20-11-2020 || Buscar | 16-08-2019 || Raspe | 01-10-2018 || Wag | 15-03-2020 || Tweet | 28-11-2020 || Fofo | 17-09-2020 || Casca | NULO || Miau | NULL |+-----------+------------+
Se tentarmos usar
AVG()
no DOB
coluna, obteremos um erro. SELECT AVG(DOB) AS Average
FROM Pets;
Resultado:
Msg 8117, Level 16, State 1, Line 1Operand data type is invalid for avg operator.
Dados de caracteres
O
AVG()
A função também não aceita expressões de cadeia de caracteres. Veja o que acontece se tentarmos usar
AVG()
no ProductName
coluna de nossos Products
table (que usa um tipo de dados de varchar):SELECT AVG(ProductName) AS Average
FROM Products;
Resultado:
Msg 8117, Level 16, State 1, Line 1Operand tipo de dados varchar é inválido para o operador avg.
O DISTINCT
Palavra-chave
Você pode usar o
DISTINCT
palavra-chave com AVG()
para calcular apenas valores distintos. Ou seja, se houver valores duplicados, eles serão tratados como um valor. Exemplo:
SELECT AVG(DISTINCT ProductPrice) AS DistinctAverage
FROM Products;
Resultado:
+-------------------+| DistinctAverage ||-------------------|| 56.868333 |+-------------------+
Podemos ver que este resultado é maior do que o resultado obtido sem o
DISTINCT
palavra-chave. Para recapitular, temos 52.457142 sem o
DISTINCT
palavra-chave e 56.868333 com o DISTINCT
palavra-chave. Isso ocorre porque existem dois itens que compartilham o mesmo preço (a chave de fenda para canhotos e a chave de fenda para destros custam 25,99). Portanto, o
AVG()
função, quando usado com o DISTINCT
palavra-chave, trata ambos os valores como um e calcula seu resultado de acordo. Funções da janela
Dependendo do seu DBMS, você pode usar um
OVER
cláusula com seu AVG()
função para criar uma função de janela. Uma função de janela executa uma operação semelhante à agregação em um conjunto de linhas de consulta. Ele produz um resultado para cada linha da consulta. Isso contrasta com uma operação agregada, que agrupa linhas de consulta em uma única linha de resultado.
Aqui está um exemplo para demonstrar o conceito.
Já vimos os
Products
tabela. Nosso banco de dados também possui um Customers
tabela e contém os seguintes dados:+--------------+-----------+-------- -----------+------------+-----------------+----------- -----+-----------+----------------+| ID do cliente | NomeDoCliente | Endereço Postal | Cidade | EstadoProvíncia | CEP | País | Telefone ||--------------+-----------------------+--------- ------+------------+-----------------+-------- ----+-----------+----------------+| 1001 | Palmeira | 20 Esplanada | Townsville | QLD | 2040 | AUS | (308) 555-0100 || 1002 | Papoula alta | 12 Estrada Principal | Colombo | OH | 43333 | EUA | (310) 657-0134 || 1003 | Criaturas loucas | 10 Loops Infinitos | Cairns | QLD | 4870 | AUS | (418) 555-0143 || 1004 | Ops Mídia | 4 Passeio à beira-mar | Perth | WA | 1234 | AUS | (405) 443-5987 || 1005 | Nomes Estranhos Inc. | Rua George, 789 | Sidney | NSW | 2000 | AUD | (318) 777-0177 || 1006 | Solucionistas Hi-Five | 5 Rua Principal | Terras Altas | HI | 1254 | AUS | (415) 413-5182 |+------------------+----------------------+---- ---------------+------------+-----------------+--- ---------+-----------+----------------+
Podemos recuperar dados dessas tabelas e apresentá-los como um conjunto de resultados usando uma junção.
Também podemos usar o
AVG()
função com o OVER
cláusula para aplicar uma função de janela aos dados. SELECT
v.VendorName,
p.ProductName,
p.ProductPrice,
AVG(ProductPrice) OVER (PARTITION BY v.VendorName) AS "Average For This Vendor"
FROM Products p
INNER JOIN Vendors v
ON v.VendorId = p.VendorId
ORDER BY VendorName, ProductPrice, "Average For This Vendor";
Resultado:
+---------------+----------------------------- ---+----------------+---------------------------+| Nome do Fornecedor | NomeDoProduto | Preço do produto | Média para este fornecedor ||---------------+-------------------------------------- -----+----------------+--------------------------- || Gatinhos Katty | Canecas de café sem fundo (pacote com 4) | 9,99 | 9,990000 || Marte Suprimentos | Peso Longo (verde) | 11,99 | 19,680000 || Marte Suprimentos | Peso Longo (azul) | 14,75 | 19,680000 || Marte Suprimentos | Chave de fenda para destros | 25,99 | 19,680000 || Marte Suprimentos | Chave de fenda para canhotos | 25,99 | 19,680000 || Medalhas do Pedal | Caixa de palha | NULO | 245,000000 || Medalhas do Pedal | Motosserra | 245,00 | 245,000000 || Randy Telhados | Marreta | 33,49 | 33,490000 |+---------------+------------------------------------------ --+----------------+---------------------------+
Neste caso usamos oOVER
cláusula com nossoAVG()
função para particionar o resultado pelo nome do fornecedor.
Ao fazer isso, conseguimos retornar informações de preço para cada produto, bem como o preço médio de todos os produtos daquele fornecedor. O preço médio muda à medida que o fornecedor muda (a menos que vários fornecedores tenham a mesma média), mas permanece o mesmo para todos os produtos do mesmo fornecedor.
Este conceito também pode ser aplicado a outras funções agregadas em SQL, comoSUM()
,MIN()
,MAX()
eCOUNT()
.