Você está na página 1de 5

CAP T U L O

SQL

Solues dos exerccios prticos


3.1 Nota: A relao participou relaciona motoristas, carros e acidentes. a. Nota: Isso no o mesmo que o nmero total de acidentes em 1989. Precisamos contar pessoas com vrios acidentes apenas uma vez. select count (distinct nome) from acidente, participou, pessoa where acidente.nmero_relatrio = participou.nmero_relatrio and participou.id_motorista = pessoa.id_motorista and data between date 1989-00-00 and date 1989-12-31 b. Consideramos que o motorista foi Jones, embora pudesse ter sido qualquer outro. Alm disso, consideramos que Jones possui um Toyota. Primeiro, precisamos encontrar a licena do carro dado. Depois, as relaes participou e acidente precisam ser atualizadas para registrar o acidente e associ-lo ao carro dado. Consideramos os valores Berkeley para local, 2001-09-01 para data, 4007 para nmero_relatrio e 3000 para grau de dano. insert into acidente values (4007, 2001-09-01, Berkeley) insert into participou select o.id_motorista, c.licena, 4007, 3000 from pessoa p, possui o, carro c where p.nome = Jones and p.id_motorista = o.id_motorista and o.licena = c.licena and c.modelo = Toyota c. Como modelo no uma chave da relao carro, podemos considerar que apenas um dos carros de John Smith um Mazda, ou excluir todos os Mazdas de John Smith (a consulta a mesma). Novamente, consideramos que nome uma chave para pessoa. delete carro where modelo = Mazda and licena in (select licena from pessoa p, possui o where p.nome = John Smith and p.id_motorista = o.id_motorista) Nota: Os registros possui, acidente e participou associados ao Mazda ainda existem.

Sis tema d e Banco de Dados 3.2 Consulta: select e.nome_funcionrio, cidade from funcionrio e, trabalha w where w.nome_empresa = First Bank Corporation and w.nome_funcionrio = e.nome_funcionrio

ELSEVIER

b. Se as pessoas puderem trabalhar para vrias empresas, a seguinte soluo listar apenas aquelas que ganham mais de US$ 10.000 por ano somente do First Bank Corporation. select * from funcionrio where nome_funcionrio in (select nome_funcionrio) from trabalha where nome_empresa = First Bank Corporation and salrio = 10000) Como na soluo consulta anterior, podemos usar uma juno para resolver esta tambm. c. A soluo a seguir considera que todas as pessoas trabalham exatamente para uma empresa. select nome_funcionrio from trabalha where nome_empresa First Bank Corporation Se for permitido que as pessoas apaream no banco de dados (por exemplo, em funcionrio) mas no apaream em trabalha, ou se as pessoas puderem ter cargos em mais de uma empresa, a soluo um pouco mais complicada. select nome_funcionrio from funcionrio where nome_funcionrio not in (select nome_funcionrio from trabalha where nome_empresa = First Bank Corporation) d. A soluo a seguir considera que todas as pessoas trabalham para pelo menos uma empresa. select nome_funcionrio from trabalha where salrio > all (select salrio from trabalha where nome_empresa = Small Bank Corporation) Se as pessoas puderem trabalhar para vrias empresas e quisermos considerar os ganhos totais de cada pessoa, o problema mais complexo. Ele pode ser resolvido usando uma subconsulta aninhada, mas ilustramos abaixo como resolv-lo usando a clusula with. with salrio_total_funcionrio as (select nome_funcionrio, sum(salrio) as salrio_total from trabalha group by nome_funcionrio )

SQL select nome_funcionrio from salrio_total_funcionrio where salrio_total > all (select salrio_total from salrio_total_funcionrio, trabalha where trabalha.nome_empresa = Small Bank Corporation and salrio_total_funcionrio.nome_funcionrio = trabalha.nome_funcionrio )

e. A soluo mais simples usa a comparao contains que foi includa na linguagem System R Sequel original mas no est presente nas verses SQL subseqentes. select T.nome_empresa from empresa T where (select R.cidade from empresa R where R.nome_empresa = T.nome_empresa) contains (select S.cidade from empresa S where S.nome_empresa = Small Bank Corporation) Abaixo est uma soluo usando o padro SQL. select S.nome_empresa from empresa S where not exists ((select cidade from empresa where nome_empresa = Small Bank Corporation) except (select cidade from empresa T where S.nome_empresa = T.nome_empresa)) f. Consulta: select nome_empresa from trabalha group by nome_empresa having count (distinct nome_funcionrio) >= all (select count(distinct nome_funcionrio) from trabalha group by nome_empresa) g. Consulta: select nome_empresa from trabalha group by nome_empresa having avg (salrio) > (select avg (salrio) from trabalha where nome_empresa = First Bank Corporation)

Sis tema d e Banco de Dados 3.3 a. A soluo considera que cada pessoa possui apenas uma tupla na relao funcionrio. update funcionrio set cidade = Newton where nome_pessoa = Jones b. Consulta: update trabalha T set T.salrio = T.salrio * 1.03 where T.nome_funcionrio in (select nome_gerente from gerencia) and T.salrio * 1.1 > 100000 and T.nome_empresa = First Bank Corporation update trabalha T set T.salrio = T.salrio * 1.1 where T.nome_funcionrio in (select nome_gerente from gerencia) and T.salrio * 1.1 <= 100000 and T.nome_empresa = First Bank Corporation

ELSEVIER

A SQL-92 fornece uma operao case (veja o Exerccio 3.5), a qual nos fornece uma soluo mais concisa: update trabalha T set T.salrio = T.salrio * (case when (T.salrio * 1.1 > 100000) then 1.03 else 1.1 ) where T.nome_funcionrio in (select nome_gerente from gerencia) and T.nome_empresa = First Bank Corporation 3.4 Consulta: select coalesce(a.nome, b.nome) as nome, coalesce(a.endereo, b.endereo) as endereo, a.cargo, b.salrio from a full outer join b on a.nome = b.nome and a.endereo = b.endereo 3.5 Usamos a operao case fornecida pela SQL-92: a. Para exibir a nota de cada aluno: select id_aluno, (case when pontuao < 40 then F, when pontuao < 60 then C, when pontuao < 80 then B, else A end) as nota from marcas

SQL

b. Para encontrar o nmero de alunos com cada nota, usamos a seguinte consulta, onde notas o resultado da consulta dada como a soluo para a parte 0.a. select nota, count(id_aluno) from notas group by nota 3.6 A consulta seleciona os valores de p.a1 que so iguais a algum valor de r1.a1 ou r2.a1 se, e somente se, r1 e r2 no forem vazios. Se um ou ambos de r1 e r2 forem vazios, o produto cartesiano de p, r1 e r2 ser vazio e, portanto, o resultado da consulta ser vazio. claro, se o prprio p for vazio, o resultado ser como esperado, ou seja, vazio. 3.7 Para inserir a tupla (Johnson, 1900) na view info_emprstimo, podemos fazer o seguinte: tomador (Johnson, ^k) tomador emprstimo (^k, ^, 1900) emprstimo tal que ^k seja um novo nulo marcado ainda no existente no banco de dados.