SQL Queries and Database Triggers Examples
SQL Queries Examples
Page 22 Exercises
Exercise 5
Buscar o nome e a idade em meses dos pacientes:
SELECT nome, (idade*12) as "Idade em meses" FROM Pacientes;
Exercise 7
Qual o menor e o maior salário dos funcionários de Florianópolis?
SELECT MIN(salario), MAX(salario) FROM Funcionarios WHERE cidade='Florianopolis';
Exercise 11
Qual a média de idade dos médicos e o total de ambulatórios atendidos por eles?
SELECT AVG(idade), count(distinct nroa) FROM Medicos;
Exercise 12
Buscar o código, o nome e o salário líquidos dos funcionários. O salário líquido é obtido pela diferença entre o salário cadastrado menos 20% deste mesmo salário:
SELECT codf, nome, (salario*0.8) AS "Salário Líquido" FROM Funcionarios;
Exercise 15
Buscar o nome e CPF dos funcionários que não possuam a sequência “00000” em seus CPFs:
SELECT nome, cpf FROM Funcionarios WHERE cpf NOT LIKE '%00000%';
Exercise 16
Buscar os códigos e nomes dos pacientes com mais de 25 anos que estão com tendinite, fratura, gripe e sarampo.
SELECT codp, nome FROM Pacientes WHERE idade>25 AND doenca IN('tendinite', 'fratura', 'gripe', 'sarampo');
Page 31 Exercises
Exercise 1
Buscar nome e cpf dos médicos que também são pacientes do hospital:
SELECT m.nome, m.cpf FROM Medicos m JOIN Pacientes p ON m.cpf=p.cpf;
OU
SELECT m.nome, m.cpf FROM Medicos m, Pacientes p WHERE m.cpf=p.cpf;
Database Views, Permissions and Triggers
Permissions
1.1)
GRANT INSERT, UPDATE, DELETE, SELECT ON Pacientes TO médico;
1.2)
CREATE VIEW vEstagiario AS SELECT m.nome, p.nome, Data FROM Medicos m JOIN Consultas c ON m.codm=c.codm JOIN Pacientes p ON c.codp = p.codp;
GRANT SELECT ON vEstagiario TO estagiário;
1.3)
CREATE VIEW vMedicos4 AS SELECT m.* FROM Medicos m JOIN Ambulatorios a ON a.nroa = m.nroa WHERE a.andar = 4;
GRANT INSERT, UPDATE, DELETE, SELECT ON vMedicos4 TO secretária;
1.4)
CREATE ROLE QUERY;
GRANT SELECT ON Pacientes, Medicos TO QUERY;
GRANT QUERY TO U1, U2;
Triggers
2.1)
CREATE TRIGGER fReduçãoSalario BEFORE UPDATE OF salario ON Funcionarios FOR EACH ROW EXECUTE PROCEDURE verificaSalario();
CREATE FUNCTION verificaSalario() RETURNS trigger as $$ BEGIN IF new.salario
2.2)
CREATE TRIGGER cpfDuplicado BEFORE INSERT ON Pacientes FOR EACH ROW EXECUTE PROCEDURE verificaCPF();
CREATE FUNCTION verificaCPF() RETURNS trigger as $$ DECLARE linhas_afetadas integer DEFAULT 0; BEGIN EXECUTE SELECT * FROM Medicos WHERE cpf = new.cpf; GET DIAGNOSTICS linhas_afetadas = ROW_COUNT; IF linhas_afetadas > 0 THEN RAISE NOTICE 'Inclusão não autorizada! O CPF já está sendo usado como CPF de um médico!'; END IF; END; $$ LANGUAGE plpgsql;
2.3)
CREATE TRIGGER mResponsavel BEFORE INSERT ON Medicos FOR EACH ROW EXECUTE PROCEDURE ambulatorioResp();
CREATE FUNCTION ambulatorioResp() RETURNS trigger as $$ DECLARE linhas_afetadas integer DEFAULT 0; BEGIN EXECUTE SELECT * FROM Medicos WHERE nroa = new.nroa; GET DIAGNOSTICS linhas_afetadas = ROW_COUNT; IF linhas_afetadas > 0 THEN RAISE NOTICE 'Inserção não autorizada! Este ambulatório já possui um responsável!'; END IF; END; $$ LANGUAGE plpgsql;
2.4)
CREATE TRIGGER medicosemAmb BEFORE UPDATE OF nroa ON Medicos FOR EACH ROW EXECUTE PROCEDURE removerMedico();
CREATE FUNCTION removerMedico() RETURNS trigger as $$ BEGIN IF new.nroa = NULL THEN EXECUTE DELETE FROM Medicos WHERE new.codm = codm; END IF; END; $$ LANGUAGE plpgsql;
2.5)
CREATE TRIGGER rvAmbulatorio BEFORE DELETE ON Ambulatorios FOR EACH ROW EXECUTE PROCEDURE realocarCapacidade();
CREATE FUNCTION realocarCapacidade() RETURNS trigger as $$ DECLARE row RECORD; BEGIN FOR row IN SELECT * FROM ambulatorios WHERE andar = old.andar LOOP EXECUTE UPDATE ambulatorios SET capacidade = capacidade + old.capacidade WHERE nroa = row.nroa; EXIT; END LOOP; END; $$ LANGUAGE plpgsql;
Advanced SQL Queries
a) Buscar o nome dos atletas que participaram (tem aproveitamento) em TODOS os times patrocinados pelo patrocinador cujo nome é ‘Rainha Malhas’
SELECT nome FROM Atletas a WHERE NOT EXISTS(Select * From Times t Where codidoPatrocinador=(Select codigoPatrocinador From Patrocinadores Where nome='Rainha Malhas' And NOT EXISTS(Select * From Aproveitamento ap Where ap.codigoAtleta=a.codigoAtleta And ap.codigoTime=t.codigoTime));
b) Alterar a data para ‘20016-10-10’ dos aproveitamentos que se referem aos times que possuem o maior score dentre todos os times
UPDATE Aproveitamento SET data='2016-10-10' WHERE codigoTime IN (Select codigoTime From Times where score=(Select MAX(score) From Times));
c) Buscar o nome dos atletas e dos times que possuem aproveitamento na partida mais recente. A partida mais recente corresponde a maior data registrada na relação Aproveitamento, Se houver empate, mostrar todos os dados requisitados referentes a essa maior data.
SELECT a.nome, t.nome FROM Aproveitamento ap JOIN Atletas a ON ap.codigoAtleta=a.codigoAtleta JOIN Times t ON ap.codigoTime = t.codigoTime WHERE data = (SELECT MAX(data) From Aproveitamento);
d) Buscar o nome dos patrocinadores que patrocinam APENAS times da modalidade com nome ‘Tênis de Mesa’.
SELECT p.nome FROm Patrocinadores p JOIN Times t ON p.codigoPatrocinador=t.codigoPatrocinador AND p.codigoPatrocinador NOT IN(Select codigoPatrocinador From Times Where codigoModalidade IN (Select codigoModalidade From Modalidades Where nome != 'Tênis de Mesa'));
e) Com frequência o sistema precisa saber quais são os times que possuem score inferior a 3 e quais seus times reserva, caso existir. Formule uma visão capaz de fornecer o código e nome de TODOS os times com score inferior a 3. Caso o time possua um time reserva, apresentar também o nome e score do time que se refere ao time reserva dele.
CREATE VIEW vScore3 AS SELECT t1.codigoTime, t1.nome, t2.nome, t2.score FROM Times t1 LEFT JOIN Times t2 ON t1.timeReserva=t2.codigoTime WHERE t1.score < 3;