Prova de Fundamentos de Bancos de Dados - Inf

Propaganda
Prova de Fundamentos de Bancos de Dados
2a Prova
Prof. Carlos A. Heuser
Junho de 2009
Prova com consulta – duas horas de duração
Considere a base de dados abaixo (base de dados idêntica a da 1a prova). Esta base de
dados é usada para gerência de clínicas médicas.
/* tabela de clínicas médicas */
Clinica(CodCli,NomeCli,LocalCli)
/* tabela de médicos */
Medico(CodMed,NomeMed,CodEspeci)
CodEspeci referencia Especialidade
/* tabela que relaciona médicos a clínicas */
ClinicaMedico(CodCli,CodMed)
CodCli referencia Clinica,
CodMed referencia Medico
/* tabela coma agenda das consultas dos médicos */
AgendaConsulta(CodCodCli,CodMed,Data,Hora)
(CodCli,CodMed) referencia ClinicaMedico
/* tabela com as especialidades que os médicos podem ter - para cada especialidade,
pode ser indicada uma especialidade mais genérica (por exemplo ’cirurgia geral’ pode ser
uma especialidade mais genérica que ’cirurgia pediátrica’); isto é indicado pela coluna
CodEspeciGenerica*/
Especialidade(CodEspeci,Nome,CodEspeciGenerica)
CodEspeciGenerica
referencia Especialidade
1
1. (Peso 1,25) Sobre a base de dados acima, resolver a seguinte consulta usando cálculo relacional:
Obter os códigos dos médicos que atuam em todas clínicas cadastradas no banco
de dados (se a base de dados não contiver nenhuma clínica, todos médicos devem
aparecer no resultado).
Solução:
{r|
∀ c ∈ Clinica (
∃ cm ∈ ClinicaMedico (
cm.CodCli=c.CodCli ∧
cm.CodMed=r.CodMed
)
)
}
2. Sobre a base de dados acima, resolver as consultas abaixo usando SQL:
2.a (Peso 1,25) Obter os códigos e nomes dos médicos que não atuam em nenhuma clínica.
Solução:
SELECT CodMed, NomeMed
FROM Medico
EXCEPT
(SELECT CodMed, NomeMed
FROM Medico
NATURAL JOIN
ClinicaMedico
)
ou
SELECT CodMed, NomeMed
FROM Medico
WHERE
CodMed NOT IN
(SELECT CodMed
FROM ClinicaMedico
)
ou
2
SELECT CodMed, NomeMed
FROM Medico
WHERE
NOT EXISTS
(SELECT *
FROM ClinicaMedico
WHERE CodMed = Medico.CodMed
)
ou
SELECT CodMed, NomeMed
FROM Medico
LEFT NATURAL JOIN
ClinicaMedico
WHERE
ClinicaMedico.cODcLI IS NULL
3
2.b (Peso 1,25) Obter uma tabela contendo as seguintes colunas:
i. Código e nome de cada especialidade;
ii. código e nome de cada médico que atua nesta especialidade (se a especialidade não tiver médicos, estas colunas devem aparecer em branco);
iii. código e nome de cada clínica em que atua o médico (se o médico não
atua em nenhuma clínica, estas colunas devem aparecer vazias).
Solução:
SELECT
Especialidade.CodEspci,
Especialidade.Nome,
Medico.CodMed,
Medico.NomeMed,
Clinica.CodCli,
Clinica.NomeCli
FROM Especialidade
NATURAL LEFT JOIN
Medico
NATURAL LEFT JOIN
ClinicaMedico
NATURAL LEFT JOIN
Clinica
2.c (Peso 1,25) Obter uma tabela com duas colunas:
i. Nome de uma especialidade mais genérica, seguida de
ii. nome de uma especialidade mais específica (apenas se houver uma especialidade mais específica para a especialidade em questão).
A tabela não deve ser recursiva, ou seja apenas um nível de relacionamento
deve aparecer.
Solução:
SELECT EspecialidadeGenerica.Nome,
EspecialidadeEspecifica.Nome
FROM Especialidade as EspecialidadeGenerica,
Especialidade as EspecialidadeEspecifica,
WHERE
EspecialidadeEspecifica.CodEspeciGenerica=
EspecialidadeGenerica.CodEspeci
4
2.d (Peso 1,25) – Mesmo enunciado que a questão 1
Obter os códigos dos médicos que atuam em todas clínicas cadastradas no
banco de dados (se a base de dados não contiver nenhuma clínica, todos médicos devem aparecer no resultado).
Solução:
SELECT Medico.CodMed,
FROM
Medico
WHERE
NOT EXISTS (
SELECT * FROM Clinica
WHERE
NOT EXISTS (
SELECT * FROM ClinicaMedico
WHERE Clinica.CodCli
= ClinicaMedico.CodCli AND
Medico.CodMed
= ClinicaMedico.CodMed
)
)
2.e (Peso 0,625) Obter o número de clínicas que têm uma localidade informada.
Solução:
SELECT COUNT (LocalCli)
FROM Clinica
2.f (Peso 0,625) Obter o número de clinicas que têm pelo menos um médico.
Solução:
SELECT COUNT (DISTINCT CodCli)
FROM ClinicaMedico
2.g Para cada especialidade, obter:
i. O código e o nome do especialidade, seguido do
ii. número de médicos que atuam na especialidade.
Resolver esta consulta considerando duas variantes:
i. (Peso 1,25) Mesmo especialidades nas quais não aparecem médicos devem aparecer no resultado.
Solução:
SELECT Especialidade.CodEspeci,
Especialidade.Nome
COUNT (CodMed) AS NoDeMedicos
FROM Especialidade
NATURAL LEFT JOIN
Medico
GROUP BY Especialidade.CodEspeci,
Especialidade.Nome
5
ii. (Peso 1,25) Apenas as especialidades com mais que trinta médicos devem
aparecer no resultado.
Solução:
SELECT Especialidade.CodEspeci,
Especialidade.Nome
COUNT (*) AS NoDeMedicos
FROM Especialidade
NATURAL JOIN
Medico
GROUP BY Especialidade.CodEspeci,
Especialidade.Nome
HAVING COUNT (*) > 30
6
Download