Consultas del Trabajo Práctico Grupal. Para acceder a la base de datos: Agenda Médica con usuario y password: test. http://apex.oracle.com/pls/otn/f?p=26093:1 Para realizar las consultas se deben utilizar , sin excepción , las tablas de la base de datos del link precitado. Utilizando únicamente las sentencias y cláusulas especificadas en la cartilla de sintaxis SQL incluída en el apunte. Obtener: 1. El apellido y el nombre de los profesionales que no atienden los días lunes. select p.apellido, p.nombre from profesional p where p.idprofesional not in (select b.idprofesional from bloque b where b.diasemana='LU' ) 2. La/s fecha/s en que el profesional ‘Juan Perez’, atiende su mayor cantidad diaria de pacientes. select a1.fecha from agenda a1, profesional p1 where a1.idprofesional = p1.idprofesional and p1.nombre = 'JUAN' and p1.apellido = 'PEREZ' group by a1.fecha having count(*) = (select max(count(*)) from agenda a2, profesional p2 where a2.idprofesional = p2.idprofesional and p2.nombre = 'JUAN' and p2.apellido = 'PEREZ' group by a2.fecha) 3. El número, apellido, nombre de paciente y la fecha, hora de inicio, hora de fin, especialidad de los turnos asignados a un paciente que se superpongan con otros turnos asignados al mismo paciente ordenado ascendentemente por número de paciente, fecha y hora de inicio del turno. select p1.nropaciente, p1.apellido, p1.nombre, a1.fecha, a1.horainicio, a1.horafin, a1.especialidad from paciente p1, agenda a1, comprobante c1 where p1.nropaciente=c1.nropaciente and c1.fecha=a1.fecha and c1.nroturno= a1.nroturno and c1.especialidad=a1.especialidad and c1.nrobloque=a1.nrobloque and c1.idprofesional=a1.idprofesional and exists (select * from agenda a2, comprobante c2 where c2.fecha=a2.fecha and c2.nroturno= a2.nroturno and c2.especialidad=a2.especialidad and c2.nrobloque=a2.nrobloque and c2.idprofesional=a2.idprofesional and c1.nropaciente=c2.nropaciente and c1.nrocomprobante <> c2.nrocomprobante and a1.fecha=a2.fecha and ( (a2.horainicio > a1.horainicio and a2.horainicio < a1.horafin) or (a2.horafin > a1.horainicio and a2.horafin < a1.horafin) or (a1.horainicio > a2.horainicio and a1.horainicio < a2.horafin) or (a1.horafin > a2.horainicio and a1.horafin < a2.horafin) ) ) order by p1.nropaciente, a1.fecha, a1.horainicio asc 4. Las especialidades que se atiendan ( bloques asignados ) en promedio más veces por día los fines de semana que los días laborales (lunes a viernes). select b1.especialidad from bloque b1 where (b1.diasemana = 'SA' or b1.diasemana = 'DO') group by b1.especialidad having (count(*) / 2) > ( select (count(*) / 5) from bloque b2 where not (b2.diasemana = 'SA' or b2.diasemana = 'DO') and b2.especialidad=b1.especialidad group by b2.especialidad ) Si la especialidad no está siendo atendida en el fin de semana, directamente no aparece en el primer select (tiene sentido para la consulta, ya que pide un “mayor estricto”). Si la especialidad no está siendo atendida durante la semana el segundo select debería dar 0, pero da “no data found” haciendo que la comparación tenga un comportamiento desconocido. 5. Las especialidades que se atiendan ( bloques asignados ) en todos los días de la semana para los que ningún profesional admite sobreturnos . select distinct b1.especialidad from bloque b1 where not exists ( select b2.diasemana from bloque b2 where not exists (select 'especialidad atendida en el dia de la semana' from bloque b3 where b3.diasemana=b2.diasemana and b3.especialidad=b1.especialidad ) and not exists (select 'algun profesional que admita sobreturnos' from bloque b4 where b4.diasemana = b2.diasemana and maximosobreturnos > 0 ) ) La expresión completa seria: seleccionar las especialidades para las cuales no existe un dia de la semana para el cual: - esa especialidad no esté siendo atendida - No existe un profesional que admita sobre turnos bloque b2 se está usando como tabla solo para saber los dias de la semana. Está haciendolo para los dias de la semana en que ningún profesional admite sobreturrnos en cualquier especialidad. Preguntar qué son bloques asignados. Se está considerando que una especialidad está siendo atendida si existen bloques para esa especialidad. No considera que haya turnos generados para esos bloques. 6. Para cada obra social el plan con la mayor cantidad de pacientes. select p1.obrasoc, p1.plan, count(*) from paciente p1 group by p1.obrasoc, p1.plan having count(*) = (select max(count(*)) from paciente p2 where p2.obrasoc=p1.obrasoc group by p2.plan ) 7. El número y el apellido de los pacientes que se atienden con profesionales con su mismo apellido. select distinct pa.nropaciente, pa.apellido from paciente pa, comprobante c, profesional pr where c.nropaciente = pa.nropaciente and c.idprofesional = pr.idprofesional and pa.apellido = pr.apellido 8. Para cada especialidad del profesional ‘Pedro Artigas’ la identificación y la hora de inicio de los turnos disponibles ordenado ascendentemente por fecha y hora de inicio. select a.especialidad, a.fecha, a.nroturno, a.horainicio from profesional p, agenda a where a.idprofesional = p.idprofesional and p.nombre = 'PEDRO ' and p.apellido = 'ARTIGAS ' order by a.especialidad, a.fecha, a.horainicio asc 9. Las fechas y la identificación de los bloques que tengan más del 60 % de sus turnos asignados. Considero los bloques que tienen más del 60% de sus turnos asignados a algún paciente. select a1.idprofesional, a1.especialidad, a1.nrobloque, a1.fecha from agenda a1 group by a1.idprofesional, a1.especialidad, a1.nrobloque, a1.fecha having count(*) * 0.6 < (select count(*) from agenda a2 where a2.idprofesional = a1.idprofesional and a2.especialidad = a1.especialidad and a2.nrobloque = a1.nrobloque and a2.fecha = a1.fecha and exists (select 'algun comprobante para el turno ' from comprobante c where c.idprofesional = a2.idprofesional and c.especialidad = a2.especialidad and c.nrobloque = a2.nrobloque and c.fecha = a2.fecha and c.nroturno = a2.nroturno ) group by a2.idprofesional, a2.especialidad, a2.nrobloque, a2.fecha ) El primer select busca todos los turnos que están en la agenda y los agrupa por bloque, contando la cantidad total de turnos para ese bloque. El segundo select cuenta la cantidad de turnos asignados a un paciente para un bloque El tercer select busca si hay algun comprobante para un turno determinado, es decir, que el turno esté asignado a algún paciente. 10. El apellido y el nombre de los profesionales que atienden todos los días de la semana en que se atienden todos los pacientes de GALENO. a) Consulta intermedia: días de la semana en que se atienden todos los pacientes de GALENO select distinct b1.diasemana from bloque b1 where not exists (select p.nropaciente from paciente p where p.obrasoc = 'GALENO' and not exists (select 'paciente atendiendose ese dia' from comprobante c, bloque b2 where c.idprofesional = b2.idprofesional and c.especialidad = b2.especialidad and c.nrobloque = b2.nrobloque and c.nropaciente = p.nropaciente and b2.diasemana = b1.diasemana ) ) Selecciona los dias de la semana para los cuales no existe un paciente de GALENO que no se atienda. Bloque se está usando solo para saber los días de las semana b) Consulta pedida: select pr.apellido, pr.nombre from profesional pr where not exists (select distinct b1.diasemana from bloque b1 where not exists (select p.nropaciente from paciente p where p.obrasoc = 'GALENO' and not exists (select 'paciente atendiendose ese dia' from comprobante c, bloque b2 where c.idprofesional = b2.idprofesional and c.especialidad = b2.especialidad and c.nrobloque = b2.nrobloque and c.nropaciente = p.nropaciente and b2.diasemana = b1.diasemana ) ) and not exists ( select 'bloque creado para ese dia' from bloque b3 where b3.idprofesional = pr.idprofesional and b3.diasemana = b1.diasemana ) ) Selecciona los profesionales para los cuales no existe un día de la semana de los calculados anteriormente en que no atiendan. Considero que “atender un día” significa que existe un bloque creado para ese día, sin importar si hay turnos creados o no.