Consultas SQL Esenciales para Gestión de Hoteles y Personal
Clasificado en Diseño e Ingeniería
Escrito el en español con un tamaño de 7,85 KB
Consultas SQL Esenciales para Gestión de Hoteles y Personal
Este documento presenta una serie de ejercicios prácticos de SQL, diseñados para resolver problemas comunes en la gestión de bases de datos relacionadas con alojamientos, personal, habitaciones y actividades. Cada punto incluye el enunciado del problema y su correspondiente consulta SQL optimizada.
11. Empleado con la fecha de alta más temprana
Obtener todos los datos del empleado que comenzó a trabajar en la empresa en la fecha más antigua.
SELECT *
FROM Personal
WHERE idTrabajador = (
SELECT tra.idTrabajador
FROM Trabajar tra
WHERE tra.fecAlta = (
SELECT MIN(tra.fecAlta)
FROM Trabajar tra
)
);
12. Historial laboral completo de cada empleado
Generar un historial laboral detallado para cada empleado, mostrando su nombre, el alojamiento donde trabajó, y las fechas de alta y baja. La salida debe estar ordenada por el nombre del empleado y, para cada empleado, por la fecha de incorporación en el alojamiento.
SELECT
per.nombre AS NombreEmpleado,
alo.nombre AS NombreAlojamiento,
tra.fecAlta AS FechaAlta,
tra.fecBaja AS FechaBaja
FROM Personal per
JOIN Trabajar tra ON per.idTrabajador = tra.idTrabajador
JOIN Alojamientos alo ON tra.idAlojamiento = alo.idAlojamiento
ORDER BY
NombreEmpleado,
FechaAlta;
13. Conteo de habitaciones sin baño por alojamiento
Determinar el número de habitaciones que no disponen de baño en cada uno de los alojamientos.
SELECT
alo.nombre AS NombreAlojamiento,
COUNT(*) AS "Número de habitaciones sin baño"
FROM Habitaciones hab
JOIN Alojamientos alo ON hab.idAlojamiento = alo.idAlojamiento
WHERE hab.baño = 'n'
GROUP BY alo.nombre;
14. Alojamientos con más de dos contratos de personal
Identificar los alojamientos que han gestionado más de dos contratos de personal.
SELECT alo.nombre AS NombreAlojamiento
FROM Trabajar tra
JOIN Alojamientos alo ON tra.idAlojamiento = alo.idAlojamiento
GROUP BY alo.nombre
HAVING COUNT(*) > 2;
15. Precio medio de habitaciones sin baño por alojamiento
Calcular el precio medio de las habitaciones que no disponen de baño para cada alojamiento.
SELECT
alo.nombre AS NombreAlojamiento,
AVG(hab.precio) AS "Precio Medio"
FROM Habitaciones hab
JOIN Alojamientos alo ON hab.idAlojamiento = alo.idAlojamiento
WHERE hab.baño = 'n'
GROUP BY alo.nombre;
16. Alojamientos compartidos por Luis Martínez y Susana García
Encontrar los alojamientos donde tanto el Sr. Luis Martínez como la Sra. Susana García han trabajado, utilizando operaciones de intersección.
SELECT alo.nombre AS NombreAlojamiento
FROM Trabajar tra
JOIN Alojamientos alo ON tra.idAlojamiento = alo.idAlojamiento
WHERE tra.idTrabajador = (
SELECT idTrabajador
FROM Personal
WHERE nombre LIKE '%Luis Martínez%'
)
INTERSECT
SELECT alo.nombre
FROM Trabajar tra
JOIN Alojamientos alo ON tra.idAlojamiento = alo.idAlojamiento
WHERE tra.idTrabajador = (
SELECT idTrabajador
FROM Personal
WHERE nombre LIKE '%Susana García%'
);
17. Actividades con el nivel de dificultad más bajo
Mostrar el nombre y la descripción de todas aquellas actividades cuyo nivel de dificultad sea el más sencillo (mínimo).
SELECT *
FROM Actividades
WHERE dificultad = (
SELECT MIN(dificultad)
FROM Actividades
);
18. Habitaciones por tipo y alojamiento
Listar el nombre de los alojamientos junto con el número de habitaciones que poseen de cada tipo. La salida debe estar ordenada primero por el tipo de habitación (descendente) y luego por el número de habitaciones por establecimiento (descendente).
SELECT
COUNT(*) AS NumHabitaciones,
alo.nombre AS NombreAlojamiento,
hab.tipo AS TipoHabitacion
FROM Habitaciones hab
JOIN Alojamientos alo ON hab.idAlojamiento = alo.idAlojamiento
GROUP BY
alo.nombre,
hab.tipo
ORDER BY
TipoHabitacion DESC,
NumHabitaciones DESC;
19. Empleados sin historial laboral
Identificar a los empleados que nunca han registrado un contrato de trabajo en ningún alojamiento.
SELECT *
FROM Personal per
WHERE per.idTrabajador NOT IN (
SELECT DISTINCT idTrabajador
FROM Trabajar
);
20. Alojamientos con actividades de máxima dificultad
Obtener todos los datos de los alojamientos que ofrecen al menos una actividad con el nivel de dificultad más alto.
SELECT *
FROM Alojamientos
WHERE idAlojamiento IN (
SELECT idAlojamiento
FROM Organizar
WHERE idActividad = (
SELECT idActividad
FROM Actividades
WHERE dificultad = (
SELECT MAX(dificultad)
FROM Actividades
)
)
);
Nota: La consulta original usaba <=any
, que es equivalente a IN
para este caso. Se ha simplificado para mayor claridad.
21. Empleados actuales y datos de alojamientos en Castropol
Obtener el nombre y teléfono de los alojamientos, junto con el nombre de sus empleados actuales, para aquellos alojamientos situados en el concejo de Castropol.
SELECT
per.nombre AS NombreEmpleado,
alo.nombre AS NombreAlojamiento,
alo.telefono AS TelefonoAlojamiento
FROM Alojamientos alo
JOIN Trabajar tra ON alo.idAlojamiento = tra.idAlojamiento
JOIN Personal per ON tra.idTrabajador = per.idTrabajador
WHERE alo.direccion LIKE '%castropol%'
AND tra.fecBaja IS NULL;
22. Estadísticas de precios de habitaciones (general)
Calcular el precio mínimo, precio máximo y precio medio de todas las habitaciones en todos los alojamientos.
SELECT
AVG(precio) AS precio_medio,
MIN(precio) AS precio_minimo,
MAX(precio) AS precio_maximo
FROM Habitaciones;
23. Estadísticas de precios de habitaciones (formato específico)
Calcular el precio mínimo, precio máximo y precio medio de todas las habitaciones en todos los alojamientos, asegurando que todos los componentes de la lista de selección de salida mantengan el mismo formato decimal que el campo precio.
SELECT
CAST(AVG(precio) AS DECIMAL(10,2)) AS precio_medio,
MIN(precio) AS precio_minimo,
MAX(precio) AS precio_maximo
FROM Habitaciones;
Nota: Se ha ajustado el tipo DECIMAL(5,2)
a DECIMAL(10,2)
para permitir valores de precio más grandes si fuera necesario, manteniendo dos decimales.
24. Número de actividades por alojamiento (semanal)
Obtener el nombre de cada alojamiento y el número total de actividades que ofrece a lo largo de la semana, ordenando la salida por el número de actividades en sentido descendente.
SELECT
alo.nombre AS NombreAlojamiento,
COUNT(org.idActividad) AS "Número de Actividades"
FROM Alojamientos alo
JOIN Organizar org ON alo.idAlojamiento = org.idAlojamiento
GROUP BY alo.nombre
ORDER BY "Número de Actividades" DESC;
25. Alojamientos sin actividades de máxima dificultad
Identificar los alojamientos que no ofrecen ninguna actividad con el nivel de dificultad más alto.
SELECT *
FROM Alojamientos
WHERE idAlojamiento NOT IN (
SELECT idAlojamiento
FROM Organizar
WHERE idActividad = (
SELECT idActividad
FROM Actividades
WHERE dificultad = (
SELECT MAX(dificultad)
FROM Actividades
)
)
);
Nota: La consulta original usaba >all
, que es equivalente a NOT IN
para este caso. Se ha simplificado para mayor claridad.