Você está na página 1de 40

IOS – Instituto de Banco de Dados – Funções de Agregação

Oportunidade Social (AVG, COUNT, SUM, MAX e MIN)

1
Apresentação
O objetivo principal das funções de agregação é
criar colunas de acumuladores de um
determinado agrupamento definido pela
cláusula GROUP BY. Se esta cláusula não for
informada o retorno será sempre uma linha.

2
Funções de Agregação

Sintaxe genérica para as funções:

SELECT [DISTINCT] [<FUNCAO>( ] <Nome da coluna|*>[)]

[ WHERE <Condicional de Filtro por linha> ]

[ GROUP BY <Colunas de agrupamento, coluna1, …, coluna16> ]

[ HAVING <Condição de agrupamento> ]

3
SUM

Esta função retorna a somatória de uma coluna(s) defina pelo


usuário.

Ex. Select que retorna o total de saldo de duplicatas de clientes

SELECT SUM(A1_SALDUP)
FROM SA1990
WHERE D_E_L_E_T_ <> ‘*’

Este exemplo retorna o saldo total dos títulos em aberto eliminando


os registros excluídos da base de dados.

4
COUNT

Esta função totaliza o número de linhas na tabela, utlizando filtro


para tal. Se for informado o nome de uma coluna, a função contará
apenas as linhas que não estiverem com seu conteúdo nulo..

Ex. Select que retorna o total de linhas da tabela

SELECT COUNT(*)
FROM SA1990
WHERE D_E_L_E_T_ <> ‘*’

Este exemplo retorna o total de linhas não excluídas.

5
COUNT

Ex. Select que retorna o total de linhas da tabela,


considerando somente uma coluna

SELECT COUNT(A1_FILIAL)
FROM SA1990
WHERE D_E_L_E_T_ <> ‘*’

Este exemplo retorna o total de linhas não excluídas. Se houver


conteúdo nulo em alguma linha, esta não será contada.

6
AVG

Esta função retorna a média aritmética da coluna informada,


filtrando as linhas pela clausula where ou having.

Ex. Select para média do saldo a receber de cada cliente

SELECT AVG(A1_SALDUP)
FROM SA1990
WHERE D_E_L_E_T_ <> ‘*’

Este exemplo retorna a média da coluna A1_SALDUP, não


considerando as linhas excluídas.

7
MAX

Esta função retorna o valor máximo da coluna especificada.

Ex. Select para o maior valor da coluna R_E_C_N_O_

SELECT MAX(R_E_C_N_O_)
FROM SA1990

Este exemplo retornará o maior valor da coluna, o mesmo é muito


usado para se saber qual a próxima seqüência disponível. Nunca
despreze as linhas excluídas, por que este número é sequencial e
único na tabela.

8
MIN

Esta função retorna o valor mínimo da coluna especificada.

Ex. Select do menor valor da data de emissão do pedido

SELECT MIN(C6_EMISSAO)
FROM SC6990
WHERE C6_CLI = ‘ 123456’
AND D_E_L_E_T_ <> ‘*’

Este exemplo retorna o menor valor da coluna C6_EMISSAO.

9
GROUP BY

Esta cláusula define quais colunas determinam o agrupamento do


comando select.

Ex. Select para obter valor total de pedidos por cliente e data

SELECT C6_CLI, C6_LOJA, C6_EMISSAO, SUM(C6_VALOR) TOTAL


FROM SC6990
WHERE D_E_L_E_T_ <> ‘*’
GROUP BY C6_CLI, C6_LOJA, C6_EMISSAO

Este exemplo faz a somatória da coluna C6_VALOR, efetuando o


agrupamento do resultado por cliente, loja e data.

10
GROUP BY

Ex. Select para obter quantidade de pedidos por cliente

SELECT C6_CLI, C6_LOJA, COUNT(*) QTD_PED


FROM SC6990
WHERE D_E_L_E_T_ <> ‘*’
AND C6_EMISSAO between ‘19990101’ and ‘19990630’
GROUP BY C6_CLI, C6_LOJA

Este exemplo retorna a quantidade de pedidos, agrupando o


resultado por cliente e loja, filtrando o resultado por data de
emissão.

11
HAVING

Esta cláusula tem por finalidade filtrar os dados que estão numa condição
de agrupamento. Apesar de ser uma cláusula de filtro (semelhante à
cláusula WHERE), ela é dependente da cláusula GROUP BY.

Ex. Select para obter códigos inseridos com duplicidade

SELECT A1_COD, A1_LOJA, COUNT(*)


FROM SA1990
WHERE D_E_L_E_T_ <> ‘*’
GROUP BY A1_COD, A1_LOJA
HAVING COUNT(*) > 1

Este exemplo faz a contagem do número de ocorrências de código e loja em


duplicidade. A clausula HAVING elimina as ocorrências não duplicadas, ou
seja COUNT(*) <= 1.
12
DISTINCT

Esta cláusula elimina repetições para a coluna informada.

Ex. Select para obter todos os CFOs utilizados pelo cliente

SELECT DISTINCT F4_CF


FROM SF4990
WHERE D_E_L_E_T_ <> ‘*’

Este exemplo elimina do resultado os CFO’s repetidos.

13
DISTINCT

Ex. Select para obter código das filiais com linhas


existentes (válido para tabela com X2_MODO = ‘E’)

SELECT DISTINCT A1_FILIAL


FROM SA1990
WHERE D_E_L_E_T_ <> ‘*’

14
SUBSTRING

Sintaxe genérica para as funções:

SUBSTR[ING](<Origem>,<n posição inicial>,<tamanho em bytes>)

Ex. Select para apresentar parte do nome do cliente para todos os clientes
que possuem ‘5’ na segunda posição do código.

SELECT SUBSTRING(A1_NOME,1,20) NOME


FROM SA1990
WHERE SUBSTRING(A1_CODIGO,2,1) = ‘5’
AND D_E_L_E_T_ <> ‘*’

Não recomendamos a utilização da função na cláusula WHERE, pois o banco


terá que fazer uma busca em toda a tabela, por não possuir índice do
conteúdo a ser filtrado.
15
JOINS

Esta operação é uma das mais poderosas expressões de um comando


SELECT, pois com ela podemos relacionar tabelas obtendo
informações cruzadas. Este comando pode ser escrito de duas
formas, porém alguns bancos suportam apenas uma delas.
Estaremos apresentado esta forma e comentaremos suas diferenças.

O relacionamento entre as tabelas é feito utilizando o símbolo de


igualdade entre duas colunas, sendo uma coluna de cada tabela.
Lembre-se que o relacionamento é feito de forma binária, ou seja, só
podemos relacionar duas tabelas de cada vez, mas podemos com isto
relacionar quantas tabelas desejarmos, limitado pela capacidade do
banco de dados.

16
JOINS

Como recomendação devemos sempre tentar relacionar no máximo quatro


tabelas, lógico que existe exceções, mas sempre que houver o
relacionamento de muitas tabelas o banco de dados precisará de mais
tempo para conseguir resolver o problema e em alguns caso não será
viável. Existem várias situações que dependem de experiência e teste para
conseguirmos chegar na melhor solução possível.

Sempre que utilizarmos JOINS devemos sempre informar todas as tabelas


que serão relacionadas na clausula FROM e todos os seus relacionamentos
na clausula WHERE se por acaso não for feito o relacionamento de uma
destas tabelas o banco de dados estará fazendo um produto cartesiano
(CROSS JOIN) entre todas as linhas da tabela que não foi relacionado com as
demais tabelas. Se isto acontecer o servidor poderá ter sérios problemas de
uso excessivo de CPU. Existem Cinco tipos de JOINS:

17
INNER JOIN

Um JOIN simples é formado pelo relacionamento de duas ou mais


tabelas.

Ex. Select para retornar todas os pedidos de venda e o nome do cliente

SELECT SC5.C5_NUM, SA1.A1_NOME


FROM SC5990 SC5, SA1990 SA1
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1
AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'

18
INNER JOIN

Ex. Select para retornar todas os pedidos de venda, nome do cliente


e o nome do Vendedor

SELECT SC5.C5_NUM, SA1.A1_NOME, SA3.A3_NOME


FROM SC5990 SC5, SA1990 SA1, SA3990 SA3
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND SA3.A3_FILIAL = ‘01’
AND SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1
AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1
AND SA1.A1_VEND = SA3.A3_COD <= Define o rel.SA1->SA3
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'
19
LEFT JOIN

O resultado de um LEFT JOIN inclui todas as linhas da tabela que foi


específica a esquerda da clausula LEFT OUTER, ou seja, independente
de existir ou não um dado relacionado na tabela informada mais a
direita da tabela todas as linhas referentes a tabela da esquerda
serão retornadas. Nas linhas que não existe um linha de relação com
a tabela a direita os campos desta tabela serão retornados com valor
nulo.

O símbolo ( *= ) representa um LEFT JOIN para o MSSQL Server,


Sybase, o campo indicado do lado do símbolo (*) será o da tabela que
você deseja que todas as linhas sejam retornadas independente da
existência do dado da coluna mais a direita, vamos ver exemplos de
query’s para estes Bancos de Dados.

20
LEFT JOIN

Ex. Select para retornar todas os pedidos de venda e o nome do


cliente mesmo que não exista o cliente

SELECT SC5.C5_NUM, SA1.A1_NOME


FROM SC5990 SC5, SA1990 SA1
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND SC5.C5_CLIENTE *= SA1.A1_COD <= Define o rel.SC5->SA1
AND SC5.C5_LOJACLI *= SA1.A1_LOJA <= Define o rel.SC5->SA1
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'

21
LEFT JOIN

Ex. Select para retornar todas os pedidos de venda, nome do cliente


e o nome do Vendedor mesmo que não exista o Vendedor

SELECT SC5.C5_NUM, SA1.A1_NOME, SA3.A3_NOME


FROM SC5990 SC5, SA1990 SA1, SA3990 SA3
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND SA3.A3_FILIAL = ‘01’
AND SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1
AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1
AND SA1.A1_VEND *= SA3.A3_COD <= Define o rel.SA1->SA3
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'
22
LEFT JOIN

O símbolo (+ ) representa um LEFT JOIN para o Oracle, o campo indicado do lado


do campo que será o da tabela que você deseja que todas as linhas sejam
retornadas independente da existência do dado da coluna mais a direita, vamos
ver exemplos de query’s para estes Bancos de Dados.

Ex. Select para retornar todas os pedidos de venda e o nome do cliente mesmo
que não exista o cliente

SELECT SC5.C5_NUM, SA1.A1_NOME


FROM SC5990 SC5, SA1990 SA1
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND (+) SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1
AND (+) SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'
23
LEFT JOIN

Ex. Select para retornar todas os pedidos de venda, nome do cliente e o


nome do Vendedor mesmo que não exista o Vendedor

SELECT SC5.C5_NUM, SA1.A1_NOME, SA3.A3_NOME


FROM SC5990 SC5, SA1990 SA1, SA3990 SA3
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND SA3.A3_FILIAL = ‘01’
AND SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1
AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1
AND (+) SA1.A1_VEND = SA3.A3_COD <= Define o rel.SA1->SA3
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'

24
LEFT JOIN

Na clausula FROM especificamos a palavra OUTER que irá representar um LEFT


JOIN para o Informix, o campo da esquerda será o da tabela que você deseja que
todas as linhas sejam retornadas independente da existência do dado da coluna
mais a direita, vamos ver exemplos de query’s para estes Bancos de Dados.

Ex. Select para retornar todas os pedidos de venda e o nome do cliente mesmo
que não exista o cliente

SELECT SC5.C5_NUM, SA1.A1_NOME


FROM SC5990 SC5 OUTER, SA1990 SA1
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1
AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'
25
LEFT JOIN

Ex. Select para retornar todas os pedidos de venda, nome do cliente e o nome do
Vendedor mesmo que não exista o Vendedor

SELECT SC5.C5_NUM, SA1.A1_NOME, SA3.A3_NOME


FROM SC5990 SC5, SA1990 SA1 OUTER, SA3990 SA3
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND SA3.A3_FILIAL = ‘01’
AND SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1
AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1
AND SA1.A1_VEND = SA3.A3_COD <= Define o rel.SA1->SA3
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'

Nota: Não é possível fazer OUTER JOINS subsequentes, ou seja, se fizer OUTER
JOIN de uma tabela que logo em seguida tem relacionamento com outra tabela.
26
RIGHT JOIN

O resultado de um RIGHT JOIN inclui todas as linhas da tabela que


foi específica a direita da clausula RIGHT OUTER , ou seja,
independente de existir ou não um dado relacionado na tabela
informada mais a esquerda da tabela todas as linhas referentes a
tabela da direita serão retornadas. Nas linhas que não existe um
linha de relação com a tabela a direita os campos desta tabela serão
retornados com valor nulo.

O símbolo ( =* ) representa um RIGHT JOIN para o MSSQL Server,


Sybase, o campo indicado do lado do símbolo (*) será o da tabela que
você deseja que todas as linhas sejam retornadas independente da
existência do dado da coluna mais a esquerda, vamos ver exemplos
de query’s para estes Bancos de Dados.
27
RIGHT JOIN

Ex. Select para retornar todos os clientes mesmo que não exista
pedidos relacionados

SELECT SC5.C5_NUM, SA1.A1_NOME


FROM SC5990 SC5, SA1990 SA1
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND SC5.C5_CLIENTE =* SA1.A1_COD <= Define o rel.SC5->SA1
AND SC5.C5_LOJACLI =* SA1.A1_LOJA <= Define o rel.SC5->SA1
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'

28
RIGHT JOIN

O símbolo ( + ) representa um RIGHT JOIN para o Oracle, o campo indicado do lado


do símbolo (+) será o da tabela que você deseja que todas as linhas sejam
retornadas independente da existência do dado da coluna mais a esquerda,
vamos ver exemplos de query’s para estes Bancos de Dados.

Ex. Select para retornar todos os clientes mesmo que não exista pedidos
relacionados

SELECT SC5.C5_NUM, SA1.A1_NOME


FROM SC5990 SC5, SA1990 SA1
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND SC5.C5_CLIENTE = SA1.A1_COD (+) <= Define o rel.SC5->SA1
AND SC5.C5_LOJACLI = SA1.A1_LOJA (+) <= Define o rel.SC5->SA1
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'
29
RIGHT JOIN

Na clausula FROM especificamos a palavra OUTER que irá representar um RIGHT


JOIN para o Informix, o campo indicado do lado direito que você deseja que todas
as linhas sejam retornadas independente da existência do dado da coluna mais a
esquerda, vamos ver exemplos de query’s para estes Bancos de Dados.

Ex. Select para retornar todos os clientes mesmo que não exista pedidos
relacionados

SELECT SC5.C5_NUM, SA1.A1_NOME


FROM SC5990 SC5, SA1990 SA1 OUTER
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1
AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'
30
FULL JOIN

Um FULL OUTER JOIN é o resultado de um INNER JOIN +


RIGHT JOIN + LEFT JOIN , desta forma você terá o resultado
com todas as linhas da primeira tabela mais o resultado
com todas as linhas da Segunda tabela e apresentará em
mesma linha os itens que forem possíveis de
relacionamento.

31
FULL JOIN

Ex. Select para retornar todos os clientes e todos os pedidos mesmo que não
exista pedidos ou clientes relacionados

SELECT SC5.C5_NUM, SA1.A1_NOME


FROM SC5990 SC5 FULL OUTER SA1990 SA1
ON SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1
AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'

Nota: Nos demais Bancos de Dados não existem este tipo de join. Mas existem
outras formar de resolver este problema utilizando INNER JOIN + LEFT JOIN +
RIGHT JOIN

32
CROSS JOIN

É o mais simples e dificilmente utilizado, ele simplesmente faz um produto


cartesiano em as tabelas especificadas na clausula WHERE. O comando é o mesmo
em todos os Bancos de Dados.

Ex. Select para retornar todos os clientes e todos os pedidos mesmo que não
exista pedidos ou clientes relacionados

SELECT SC5.C5_NUM, SA1.A1_NOME


FROM SC5990 SC5, SA1990 SA1

Nota: Existem vários casos de programadores que esquecem de relacionar algumas


tabelas, e acontece um grande problema de performance. Se você esquecer de
relacionar uma tabela e a mesma tiver um número de linhas muito grande nós
estaremos consumindo processador e I/O de disco inutilmente.

33
UNION

A expressão UNION permite você combinar o resultado de dois ou mais


SELECTs em um único resultado. Uma das restrições para combinar o
uso de UNION é que devemos ter uma estrutura única em cada um dos
SELECTs, ou seja, os mesmos devem ter o mesmo número de colunas
devem ter tipos de dados compatíveis.

Ex. Select para retornar todos os clientes da empresa 01 e da empresa


02 desconsiderando duplicidades

SELECT A1_COD, A1_LOJA, A1_NOME


FROM SA1990
UNION
SELECT A1_COD, A1_LOJA, A1_NOME
FROM SA1010
34
UNION

Ex. Select para retornar todos os clientes da empresa 01 e da


empresa 02 considerando todas duplicidades

SELECT A1_COD, A1_LOJA, A1_NOME


FROM SA1990
UNION ALL
SELECT A1_COD, A1_LOJA, A1_NOME
FROM SA1010

Nota: Existem vários casos de programadores que esquecem de


informar a clausula ALL, e acontece um grande problema que parece
estar faltando registros de dados nos programas.

35
SUB SELECTS

SUB-SELECTS são utilizados na cláusula WHERE


onde pode ser utilizado para fazer relação de
verificação de um determinado dado da tabela
original com várias linhas de uma outra tabela sem
obrigatoriamente ser parte integrante de um JOIN.

36
SUB SELECTS

Ex. Select para retornar todos os clientes que compraram o produto ‘x’, utilizando
operador IN

SELECT DISTINCT SA1.A1_NOME


FROM SA1990 SA1, SC5990 SC5
WHERE SA1.A1_FILIAL = ' '
AND SC5.C5_FILIAL = '01'
AND SC5.C5_CLIENTE = SA1.A1_COD
AND SC5.C5_LOJACLI = SA1.A1_LOJA
AND SC5.C5_NUM IN ( SELECT C6_NUM
FROM SC6990 SC6
WHERE SC6.FILIAL = ‘ ’
AND SC6.C6_NUM = SC5.C5_NUM
AND SC6.C6_PRODUTO = ‘X’
AND SC6.D_E_L_E_T_ <> ‘*’ )
AND SC5.D_E_L_E_T_ <> '*' AND SA1.D_E_L_E_T_ <> '*'
37
SUB SELECTS

Ex. Select para retornar todos os clientes que compraram o produto ‘x’, utilizando
operador EXISTS

SELECT DISTINCT SA1.A1_NOME


FROM SA1990 SA1, SC5990 SC5
WHERE SA1.A1_FILIAL = ' '
AND SC5.C5_FILIAL = '01'
AND SC5.C5_CLIENTE = SA1.A1_COD
AND SC5.C5_LOJACLI = SA1.A1_LOJA
AND EXISTS ( SELECT *
FROM SC6990 SC6
WHERE SC6.FILIAL = ‘ ’
AND SC6.C6_NUM = SC5.C5_NUM
AND SC6.C6_PRODUTO = ‘X’
AND SC6.D_E_L_E_T_ <> ‘*’ )
AND SC5.D_E_L_E_T_ <> '*' AND SA1.D_E_L_E_T_ <> '*'
38
Exercícios

1) Cadastrar pedidos de venda em 3 meses diferentes com valores


distintos, duplicando alguns clientes
2) Efetuar uma consulta para calcular a média mensal de Faturamento
considerando 3 meses (AVG)
3) Efetuar uma consulta para calcular a quantidade de vendas realizadas
em cada mês (COUNT)
4) Efetuar uma consulta para calcular o total de vendas por cliente (SUM)
5) Efetuar uma consulta para identificar a maior venda realizada (MAX)
6) Efetuar uma consulta para mostrar a primeira venda realizada (MIN)
7) Efetuar uma consulta para verificar os clientes que compraram mais
de uma vez (HAVING)
8) Efetuar uma consulta dos campos A1_COD, A1_LOJA e A1_NOME dos
clientes ativos, baseados nas vendas (DISTINCT)

39
Dúvidas ?

Rafael Duram Santos

rafael.duram@totvs.com.br

40

Você também pode gostar