do bÁsico ao avanÇado para manipulaÇÃo e … · funções de agrupamento operam em conjuntos...
TRANSCRIPT
Após o término do Capítulo:
Identificar as funções de agrupamento.
Descrever o uso das funções de
agrupamento.
A cláusula GROUP BY.
A cláusula HAVING.
Funções de agrupamento operam em conjuntos de tuplas para dar um resultado por grupo.
EMPLOYEES
Maximum salary in
EMPLOYEES table
…
SELECT [column,] group_function(column), ...
FROM table
[WHERE condition]
[GROUP BY column]
[ORDER BY column];
SELECT AVG(salary), MAX(salary),
MIN(salary), SUM(salary)
FROM employees
WHERE job_id LIKE '%REP%';
Você pode usar AVG e SUM para dados numéricos.
SELECT MIN(hire_date), MAX(hire_date)
FROM employees;
Você pode usar MIN e MAX para datas, números e strings.
COUNT(*) retorna o nº de linhas:
COUNT(expr) retorna o nº de linhas com valores não nulos de expr: SELECT COUNT(commission_pct)
FROM employees
WHERE department_id = 80;
SELECT COUNT(*)
FROM employees
WHERE department_id = 50; 1
2
SELECT COUNT(DISTINCT department_id)
FROM employees;
◦ COUNT(DISTINCT expr) retorna o nº de valores não-nulos distintos de expr.
◦ Para mostrar o total de departamentos distintos da tabela EMPLOYEES:
Valores NULL são ignorados:
A função NVL força a inclusão de NULLs:
SELECT AVG(commission_pct)
FROM employees;
SELECT AVG(NVL(commission_pct, 0))
FROM employees;
1
2
Você pode dividir linhas em grupos menores por meio da cláusula GROUP BY.
SELECT column, group_function(column)
FROM table
[WHERE condition]
[GROUP BY group_by_expression]
[ORDER BY column];
SELECT department_id, AVG(salary)
FROM employees
GROUP BY department_id ;
Todas as colunas na lista SELECT que não são usadas na função de agrupamento deve estar na cláusula GROUP BY.
A coluna usada no GROUP BY não precisa estar na lista SELECT.
SELECT AVG(salary)
FROM employees
GROUP BY department_id ;
EMPLOYEES
Add the
salaries in the EMPLOYEES
table for
each job,
grouped by
department
…
Agrupamento por mais de uma coluna:
Qualquer coluna na lista SELECT que não for uma função agregada precisa estar no GROUP BY:
SELECT department_id, COUNT(last_name)
FROM employees;
SELECT department_id, COUNT(last_name)
*
ERROR at line 1:
ORA-00937: not a single-group group function
◦ Você NÃO pode usar a cláusula WHERE para restringir grupos.
◦ Você deve usar a cláusula HAVING para restringir grupos. ◦ Você NÃO pode usar funções de grupo na cláusula WHERE.
SELECT department_id, AVG(salary)
FROM employees
WHERE AVG(salary) > 8000
GROUP BY department_id;
WHERE AVG(salary) > 8000
*
ERROR at line 3:
ORA-00934: group function is not allowed here
Não pode usar a cláusula WHERE para restringir grupos
SELECT column, group_function
FROM table
[WHERE condition]
[GROUP BY group_by_expression]
[HAVING group_condition]
[ORDER BY column];
Quando você usa a cláusula HAVING, o servidor Oracle restringe assim:
1. Linhas são agrupadas. 2. A função de agrupamento é aplicada. 3. Grupos que satisfazem a cláusula HAVING são
exibidos.
SELECT job_id, SUM(salary) PAYROLL
FROM employees
WHERE job_id NOT LIKE '%REP%'
GROUP BY job_id
HAVING SUM(salary) > 13000
ORDER BY SUM(salary);
Objetivos:
◦ Escrever consultas com funções de agrupamento.
◦ Agrupar linhas para conseguir mais de um resultado.
◦ Restringir grupos com o HAVING.
1. O RH solicita o relatório: encontre o maior, o menor, a soma e a média dos salários de todos os empregados. Chame as colunas de Máximo, Mínimo, Total e média, respectivamente. Arredonde para exibir sem casas decimais. Salve a consulta como lab_04_04.sql.
SELECT ROUND(MAX(salary),0) "Maximum",
ROUND(MIN(salary),0) "Minimum",
ROUND(SUM(salary),0) "Sum",
ROUND(AVG(salary),0) "Average"
FROM employees;
2. Modifique a consulta anterior para calcular as mesmas informações por JOB_ID.
SELECT job_id, ROUND(MAX(salary),0) "Maximum",
ROUND(MIN(salary),0) "Minimum",
ROUND(SUM(salary),0) "Sum",
ROUND(AVG(salary),0) "Average"
FROM employees
GROUP BY job_id;
3. Escreva a query para exibir o número de pessoas com o mesmo cargo (JOB_ID).
Depois de concluído, altere a consulta permitindo ao usuário digitar o JOB_ID desejado.
SELECT job_id, COUNT(*)
FROM employees
GROUP BY job_id;
SELECT job_id, COUNT(*)
FROM employees
WHERE job_id = '&job_title'
GROUP BY job_id;
4. Faça um cálculo e mostre a diferença entre o maior e o menor salários, chamando a coluna de DIFERENÇA.
SELECT MAX(salary) - MIN(salary) DIFFERENCE
FROM employees;
5. Crie uma consulta que mostre o id do gerente e, para cada gerente, exiba o salário do empregado subordinado a ele com o menor salário. Exclua os empregados que não possuem gerente. Exclua os grupos cujo salário for $6000 ou menos. Ordene por ordem decrescente de salários.
SELECT manager_id, MIN(salary)
FROM employees
WHERE manager_id IS NOT NULL
GROUP BY manager_id
HAVING MIN(salary) > 6000
ORDER BY MIN(salary) DESC;
6. Faça uma consulta que mostre o total de empregados e, desse total, o número de empregados contratados em 1995, 1996, 1997 e 1998. Dê nomes apropriados às colunas.
SELECT COUNT(*) total,
SUM(DECODE(TO_CHAR(hire_date, 'YYYY'),1995,1,0))"1995",
SUM(DECODE(TO_CHAR(hire_date, 'YYYY'),1996,1,0))"1996",
SUM(DECODE(TO_CHAR(hire_date, 'YYYY'),1997,1,0))"1997",
SUM(DECODE(TO_CHAR(hire_date, 'YYYY'),1998,1,0))"1998"
FROM employees;
7. Crie uma consulta que mostre a função, a soma dos salários dos funcionários que exerçam essa função por departamento para os departamentos 20, 50, 80 e 90, e mostre o total dos salários de quem exerce a função, independentemente do departamento. Nomeie as colunas de forma apropriada.
SELECT job_id "Job",
SUM(DECODE(department_id , 20, salary, 0)) "Dept 20",
SUM(DECODE(department_id , 50, salary, 0)) "Dept 50",
SUM(DECODE(department_id , 80, salary, 0)) "Dept 80",
SUM(DECODE(department_id , 90, salary, 0)) "Dept 90",
SUM(salary) "Total"
FROM employees
GROUP BY job_id;