Introducción
En un proyecto reciente he tenido que preparar un sistema de reservas para un hotel. La idea es sencilla poder reservar recursos (en este caso habitaciones) entre unas fechas determinadas.
Pero además, como es un hotel se da una condición especial. La fecha de inicio y de fin no son cerradas, quiero decir que una reserva puede terminar el mismo día que otra empieza y viceversa. Por todos es sabido, que normalmente en un hotel la hora de salida es hasta las 12:00am y la hora de entrada es a partir de las 14:00pm.
¿Cómo resolverlo? Sencillo,veamoslo.
Solución
Primero suponemos un esquema tan sencillo como el siguiente:
CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ; CREATE TABLE IF NOT EXISTS `mydb`.`habitaciones` ( `numero` INT(11) NOT NULL, `nombre` VARCHAR(45) NULL DEFAULT NULL, `camas` INT(11) NULL DEFAULT NULL, `camagrande` TINYINT(1) NULL DEFAULT NULL, `disponible` TINYINT(1) NULL DEFAULT NULL, PRIMARY KEY (`numero`)) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8 COLLATE = utf8_general_ci; CREATE TABLE IF NOT EXISTS `mydb`.`reservas` ( `reserva_id` INT(11) NOT NULL AUTO_INCREMENT, `habitaciones_numero` INT(11) NOT NULL, `entrada` DATE NULL DEFAULT NULL, `salida` DATE NULL DEFAULT NULL, `nombrecliente` VARCHAR(45) NULL DEFAULT NULL, `telefono` VARCHAR(45) NULL DEFAULT NULL, PRIMARY KEY (`reserva_id`), INDEX `fk_reservas_habitaciones_idx` (`habitaciones_numero` ASC), CONSTRAINT `fk_reservas_habitaciones` FOREIGN KEY (`habitaciones_numero`) REFERENCES `mydb`.`habitaciones` (`numero`) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8 COLLATE = utf8_general_ci;
El siguiente paso paso sería crear algún dato. Una vez hecho esto, podemos considerar muchos casos posbles, buscando en Internet seguro que hay muchas aproximaciones pero la solución final que yo he encontrado y funciona perfectamente para mi caso es la siguiente:
set @dstart = date_add('2014-03-15', interval 1 day); set @dend = date_sub('2014-04-01', interval 1 day); select id, vivienda_id, arrival_date, departure_date, date_add(@dstart, interval 1 day) firstday, date_sub(@dend, interval 1 day) lastday from espana_reservations r where (arrival_date between @dstart and @dend) or (@dstart between arrival_date and departure_date)
Espero que haya sido de ayuda!
Referencias
- Manual de MySQL: 12.5. Funciones de fecha y hora
- Manual de MySQL: 3.3.4.5. Cálculos sobre fechas
excelente compañero me sirvió tu explicación ,gracias…
Me alegro, un placer compartirlo!