do bÁsico ao avanÇado para manipulaÇÃo e … · funções de agrupamento operam em conjuntos...

32
DO BÁSICO AO AVANÇADO PARA MANIPULAÇÃO E OTIMIZAÇÃO DE DADOS Fábio Roberto Octaviano

Upload: hoangcong

Post on 26-Jan-2019

212 views

Category:

Documents


0 download

TRANSCRIPT

DO BÁSICO AO AVANÇADO PARA

MANIPULAÇÃO E OTIMIZAÇÃO DE DADOS

Fábio Roberto Octaviano

Agrupamento de Dados

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

◦ AVG ◦ COUNT ◦ MAX ◦ MIN ◦ STDDEV ◦ SUM ◦ VARIANCE

Group

functions

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

EMPLOYEES

4400

9500

3500

6400

10033

Average

salary in EMPLOYEES

table for each

department

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:

SELECT department_id dept_id, job_id, SUM(salary)

FROM employees

GROUP BY department_id, job_id ;

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

EMPLOYEES

The maximum

salary

per department

when it is

greater than

$10,000

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 department_id, MAX(salary)

FROM employees

GROUP BY department_id

HAVING MAX(salary)>10000 ;

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);

SELECT MAX(AVG(salary))

FROM employees

GROUP BY department_id;

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;