Vous êtes sur la page 1sur 57

Consultas em SQL

Consultas em SQL

Consultas Bsicas
Implementando Juno
Definindo Viso
Subconsultas
Ordenando resultados
Operaes e Comparao de Conjuntos
Gerando resumos
Consultas bsicas em SQL:
select < lista de atributos>
from < lista de nomes de relao>
where < condio de seleo> ;

select A1,...,An
from R1,...,Rm
where <condio>;
(R1 x ... x Rm) [ <condio> ] [A1,...,An]

produto cartesiano seleo projeo


Esquema Exemplo

E (enome, dno, sal, localizao)


D (dno, dnome, ger)

Q1: Liste todas informaes em E sobre empregados


em Fortaleza.

select *
from E
where E.localizao = Fortaleza;
Q2: Liste todas as informaes em D

select *
from D;

A clusula where opcional.


Implementando Juno
Implementando Juno

Q3: Liste todos os empregados e o nome dos seus


departamentos

select enome, dnome


from E, D
where E.dno = D.dno;

Para resolver ambiguidades


Implementando Juno
Q4: Nome dos empregados gerenciados por Gustavo e
que tem um salrio < R$1000?

select enome
from E, D
where E.dno = D.dno AND
D.ger = gustavo AND
sal < 1000;

SQL no tem nenhum suporte especial para


juno natural
Implementando Juno

Q5: Nome dos empregados que ganham mais que


seu gerente?

select E1.enome
from E E1, D, E E2
where E1.dno = D.dno AND
D.ger = E2.enome AND
E1.sal > E2.sal;

Ns precisamos de duas cpias de E. Cria-se uma


alias para evitar ambiguidades.
Implementando Juno
Q6: Nome dos gerentes que ganham menos que os seus
empregados?

select distinct E2.enome


from E E1, D, E E2
where E1.dno = D.dno AND
D.ger = E2.enome AND
E1.sal > E2.sal;

SQL no elimina tuplas duplicadas! voc deve requisitar explicitamente


dizendo select distinct.. Caso contrrio, a resposta repetir o nome do
gerente para cada empregado que ganha mais.
Implementando Juno
PEAS (#p, pnome)
FORNECEDORES_PEAS (#f,#p,qtd)

Q7: Encontre a quantidade fornecida de cada pea.


Devem constar inclusive as peas que no so
fornecidas por nenhum fornecedor.

select pnome, qtd


from PEAS P, FORNECEDORES_PEAS FP
where P.#p *= FP.#P

Outer Join
Implementando Juno
PEAS
#p pnome
P1 mouse RESULTADO
RESULTADO
P2 teclado
#p qtd qtd
P3 monitor
P1
mouse 10 10
P4 disco rgido
P1
mouse 20 20
teclado 15
P2 15
FORNECEDORES_PEAS P3 null
monitor null
disco rgido null
#f #p qtd
F1 P1 10
F1 P2 15
F2 P1 20
Definindo Vises
Definindo Viso
Q8: Como criar uma viso para salvar o resultado de uma
consulta temporariamente?

create view <nome_da_ viso>


as <uma_consulta>

create view EDM (emp, dept, ger)


as select enome, dnome, ger
from E, D
where e.dno = d.dno;

Se desejvel, os nomes das colunas podem ser renomeados.


Definindo Viso
Q9 : Imprima o nome de todos os empregados que
ganham mais de 90% do salrio do seu gerente.

create view ESGS(e_nome, e_sal, g_nome, g_sal)


as select E1.enome, E1.sal, E2.enome, E2.sal
from E E1, D, E E2
where E1.dno = D.dno AND
D.ger = E2.enome;

select e_nome
from ESGS
where e_sal > 0.9 * g_sal;
Consultas com Subconsultas
Tipos de Subconsultas
Testa membros de um conjunto:
IN
NOT IN
Verificao de Relaes Vazias:
EXISTS
NOT EXISTS
Comparao de Conjuntos: Subconsultas
introduzidas com um operador de comparao
(=,< >, >, >=, <, <=, ou !> ) seguida por
ANY (SOME) ou ALL.
Subconsultas: Membros de um conjunto

Q10: Quem est no mesmo departamento de Vera?

select E1.enome
from E E1, E E2
where E2.enome = Vera and
E1.dno = E2.dno;

select enome
from E
where E.dno IN (NOT IN)
(select dno
from E subconsulta
where enome = Vera);
Subconsultas: Membros de um conjunto
EMP ( enome, #CI, idade) DEP ( nome, e_#CI, ... )

Q11: Nomes dos empregados que tm um dependente com


o mesmo nome do empregado?

select E.enome
from EMP E
where E.#CI IN ( select e_#CI
from DEP
where e_#CI = E.#CI AND
DEP.nome = E.enome);
Subconsultas: Membros de um conjunto
EMP ( enome, #CI, idade) DEP ( nome, e_#CI, ... )

Q11: Nomes dos empregados que tm um dependente com


o mesmo nome do empregado?

select E.enome
from EMP E
where E.enome IN ( select nome
from DEP
where e_#CI = E.#CI);
Subconsultas

Q12: Nomes dos empregados que tm um dependente com


o mesmo nome do empregado?

select E.enome
from EMP E
where EXISTS ( select *
from DEP
where e_#CI = E.#CI AND
nome = E.enome);
Subconsultas

Q13: Nomes dos empregados que no tm dependentes?

select E.enome
from EMP
where NOT EXISTS ( select *
from DEP
where e_#CI = #CI );
Subconsultas

Q14: Quem tem o maior salrio?

select enome
from E
where sal >= all (select sal
from E );

> all --- Maior do que todos


Subconsultas
Q15: Quem ganha mais do que algum no departamento
de brinquedos?
select enome
from E
where sal > any
(select sal
from E, D
where E.dno = D.dno AND
D.dnome =
brinquedo);
> any (some) --- Maior do que ao menos um.
= any e <> ANY tem o mesmo efeito de ...... ??
Ordenando resultados
Ordenando resultados
Q16: Imprima E. Ordene as tuplas pelo nmero do depto.
Para cada depto, ordene do mais alto para o mais baixo
salrio. Se existir empate de salario, use ordem alfabtica no
nome. Select *
from E
order by dno, sal DESC, enome;

Especifica ordem de apresentao na tela


enome dno sal localizao
Susana 1 3000 Rio
Maria 1 2000 Rio
Jane 1 1900 Rio
Jim 2 1500 Fortaleza
Joo 2 1500 Fortaleza
Gerando Dados de Resumo
Gerando Dados de Resumo

Funes de Agregao
GROUP BY e HAVING
COMPUTE e COMPUTE BY
Funes de Agregao
Funes de Agregao
Q17: Qual a mdia de salrio dos empregados no
departamento de brinquedos?
* Nao podemos responder em alg. rel. . mas facil em SQL.

select avg(sal)
from E, D
where E.dno = D.dno AND
D.dname = brinquedo;

Na clusula select , pode-se usar:


avg(A), sum(A), min(A), max(A), count(A)
Funes de Agregao

Q18: Quantos empregados trabalham em mais de um


departamento?

select count (distinct enome)


from E E1
where enome in
(select E.enome
from E E2
where E2.enome = E1.enome AND
E2.dno != E1.dno);
Funes de Agregao

Q19: Nome dos empregados que ganham mais que a


mdia de salrio do seu departamento ?

select enome
from E E1
where sal > all
A maioria das
(select avg(sal) consultas SQL requerem
from E E2 all aqui !
where E2.dno = E1.dno);
GROUP BY e HAVING
GROUP BY
Q20: Para cada departamento, liste o nmero total de
empregados do departamento e a soma total dos salrios.

select dnome, sum(sal), count (enome)


from E, D
where E.dno = D.dno;

Resposta errada !!! Imprime cada nome de


departamento seguido pelo salrio da companhia e
total de empregados.
brinquedo 1,000, 500 2002
Manuf 1,000, 500 2002
Pessoal 1,000, 500 2002
GROUP BY

Quando queremos que um agregado seja


computado separadamente para cada valor de um
atributo ento deveremos usar:

group by
GROUP BY

Q21: Para cada departamento, liste o nmero total de


empregados do departamento e a soma total dos
salrios.
select dnome, sum (sal), count (enome)
from E, D
where E.dno = D.dno
group by dnome;

Os atributos do grouped-by
devem ser exatamente os itens no-
agregado da linha de seleo (na maioria
das SQLs).
GROUP BY

Q22: Para cada departamento d o nmero de empregados


e a mdia de salrio.

select DNO, COUNT(*), AVG(sal)


from EMP
group by DNO;
GROUP BY
Q23: Quais departamentos tm mais empregados do que a mdia dos dept, e
uma mdia de salario por empregado mais alta que a mdia dos
departamentos?
Create View MediaDep(dnome, avgsal, noEmps)
as select dnome, avg(sal), count(enome)
from E, D
where E.dno = D.dno
group by dnome;

select dnome
from MediaDep
where avgsal > all (select avg(avgsal)
from MediaDep)
AND
noEmps > all (select avg(noEmps)
from MediaDep);
GROUP BY e HAVING
Q24: Mesma que Q22, mas exclua deptos com menos R$10000 na
soma total dos salrios dos seu empregados, e imprima a
resposta em ordem alfabtica.
Create view GrandesDeptos (dnome, avgSal, noEmps)
as select dnome, avg(sal), count(enome)
from E, D
where E.dno = d.dno
group by dnome
having sum(sal) >=10000
order by dnome;

Somente para testes em um grupo inteiro. No


para testes em tuplas. todas as condies devem
envolver agregados.
GROUP BY
Q25: Quais departamentos tm uma mdia de salrio >R$ 2.000.

select dnome, avg(sal)


from E, D
where E.dno = D.dno
group by dnome
having avg(sal) > 2.000
GROUP BY
Q25: Quais departamentos tm uma mdia de salario >R$ 2.000.
Subconsultas na Clusula FROM

select dnome
from ( select dnome, avg(sal)
from E, D
where E.dno = D.dno
group by dnome)
as resultado (dnome, avgsal)
where avgsal > 2.000

Note que no precisamos usar a clausula HAVING


Q25: Para cada empregado em dois ou mais depts, imprima o
salario total dos seus gerentes. Assuma que um dept s tem um
gerente.
Create view dois_depts
as select E1.enome, sum(E2.sal) #4
from E E1, D, E E2
where E1.dno = D.dno AND #1
E2.enome = D.ger
group by E1.enome #2
having count(*) > 1 #3
order by enome; #5

Sequencia de avaliao das consultas:


#1: primeiro, tuplas so escolhidas
#2: ento, grupos so formados
#3: ento, grupos so eliminados
#4: ento, os agregados so computados para a linha de seleo
#5: ento, as tuplas da resposta so ordenadas corretamente e impressas.

Esta sequncia de avaliao seguida por todas as consultas.


COMPUTE e COMPUTE BY
COMPUTE
TTULO (ttulo, tipo, preo)

Q26: Liste todos os tipos de livros que terminam com


info e a soma total dos seus preos.
tipo preo
select tipo, preo
DB_info 30.95
from TTULOS
DB_info 10.40
IA_info 42.05 where tipo like %info
RC_info 67.20 order by tipo, preo
sum compute SUM(preo)

150.60
COMPUTE BY
TTULO (ttulo, tipo, preo)

Q26: Liste todos os tipos de livros que terminam


com infoe a soma total dos seus preos.

tipo preo
select tipo, preo
DB_info 30.95 from TTULOS
DB_info 10.40
where tipo like %info
sum
41.35 order by tipo, preo
IA_info 42.05 compute SUM(preo) by tipo
compute SUM(preo)
42.05
sum
150.60
Operaes de Conjunto

SQL tem incorporado algumas das operaes de


conjunto da lgebra relacional
Unio (UNION)
Diferena (MINUS)
Interseo (INTERSECT)

Tuplas duplicadas so eliminadas do resultado


As relaes devem ser compatveis ( tm os
mesmos atributos e na mesma ordem).
ESQUEMA EXEMPLO

EMPREGADOS (E)

enome CPF salrio CPF_Supervisor dnumero

DEPARTAMENTOS (D)

dnome dnmero CPF_gerente

TRABALHA (T) PROJETOS (P)

CPF_Emp pnumero pnome pnmero dnmero


Operaes de Conjunto
Q27: Liste os nomes dos projetos que tm um empregado
chamado Joo Silvaque trabalha no projeto ou gerencia o
departamento que controla o projeto
select pnome
from P, D, E
where P.dnum=D. dnum and D.CPF_gerente = E.CPF and
E.enome = Joo Silva
union
select pnome
from T, P, E
where T.pnum=P. dnum and T.CPF_emp = E.CPF and
E.enome = Joo Silva
Operaes de Conjunto
Q28: Liste os nomes dos empregados que no trabalham
em nenhum projeto

select enome
from E
MINUS (EXCEPT)
select enome
from T, E
where T.CPF_emp = E.CPF
Operaes de Conjunto
Q29: Liste os nomes dos empregados que no trabalham
em nenhum projeto

select enome
from E
where NOT EXIST (select *
from T
where T.CPF_emp = E.CPF )
Comparao de Conjuntos

SQL tem especificado o operador de comparao


de conjuntos CONTAINS
S1 CONTAINS S2
retorna Verdadeiro se S1 contm todos os valores de
S2

A maioria dos sistemas no implementam este


operador
Comparao de Conjuntos
Q30: Liste os nomes dos empregados que trabalham em
todos os projetos

select enome
from E
where ((select pnumero
from T
where T.CPF_emp = E.CPF )
Contains
(select pnumero
from P))
Comparao de Conjuntos
Q31: Liste os nomes dos empregados que trabalham em
todos os projetos

select enome
from E
where NOT EXISTS ( (select pnumero from P)
EXCEPT
(select pnumero
from T
where T.CPF_emp = E.CPF ))
Comparao de Conjuntos
Q32: Liste os nomes dos empregados que trabalham em
todos os projetos

select enome
from E
where NOT EXISTS ( select *
from P
where NOT EXITS
(select *
from T
where T.CPF_emp = E.CPF and ))
T.pnum = P.CPF ))
De AR para SQL

1: seleo select *
R[A = a] from R
where A = a;

2: projeo select A1,...,Ak


R[ A1,...,Ak] from R;

3: Produto cartesiano select *


R1 x R2 from R1, R2 ;
De AR para SQL
4:Unio select *
R1 U R2 from R1
-- sem duplicatas- union
select *
from R2;

5: Diferena select *
R1 - R2 from R1
where * not in
(select *
from R2);
De AR para SQL
5: Diferena select A1, ..., An
R1 - R2 from R1
except
select B1, ..., Bn
from R2);
6: Interseo select A1, ..., An
R1 R2 from R1
intersect
select B1, ..., Bn
from R2);