该系统是带有多个旅馆的旅馆管理软件。架构如下:
CREATE TABLE `ms_property` (
`id` int(10) NOT NULL,
`name` varchar(254) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `ms_property` (`id`, `name`) VALUES(1, 'Black Forest');
CREATE TABLE `ms_property_room` ( `id` int(10) NOT NULL, `property_id` int(10) NOT NULL,
`room_name` varchar(254) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `ms_property_room` (`id`, `property_id`, `room_name`) VALUES (1, 1, 'Standard Room'),
(2, 1, 'AC Room');
CREATE TABLE `ms_tariff_type` (
`tt_id` bigint(20) NOT NULL,
`tt_tariff_name` text
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `ms_tariff_type` (`tt_id`,`tt_tariff_name`) VALUES
(1, 'Season Rates'),
(2, 'Contracted Rates');
CREATE TABLE `room_tariff` (
`id` bigint(20) NOT NULL ,
`room_id` bigint(20) ,
`tariff_type_id` bigint(20) ,
`tariff_from` date,
`tariff_to` date,
`single_rate` int(11),
`default_rate` int(11)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `room_tariff` (`id`, `room_id`,`tariff_type_id`,`tariff_from`, `tariff_to`, `single_rate`, `default_rate`) VALUES
(1, 1, 1, '2019-01-01', '2019-01-20',1000,2000),
(2, 1, 2, '2019-02-06', '2019-02-12',5000,10000),
(3, 2, 1, '2019-03-05', '2019-04-10',8000,7000);
CREATE TABLE `tariff_hike_day` (
`id` bigint(20) NOT NULL,
`room_id` bigint(20) ,
`tariff_type_id` bigint(20) ,
`hd_tariff_from` date,
`hd_tariff_to` date,
`hd_single_rate` int(11),
`hd_default_rate` int(11),
`thd_sunday` smallint(6) COMMENT 'Is rate applicable on Sunday 1=>yes 0=>no',
`thd_monday` smallint(6) COMMENT 'Is rate applicable on Monday 1=>yes 0=>no',
`thd_thuesday` smallint(6) COMMENT 'Is rate applicable on Tuesday 1=>yes 0=>no',
`thd_wednesday` smallint(6) COMMENT 'Is rate applicable on Wednesday 1=>yes 0=>no',
`thd_thursday` smallint(6) COMMENT 'Is rate applicable on Thursday 1=>yes 0=>no',
`thd_friday` smallint(6) COMMENT 'Is rate applicable on Friday 1=>yes 0=>no',
`thd_saturday` smallint(6) COMMENT 'Is rate applicable on Saturday 1=>yes 0=>no'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `tariff_hike_day` (`id`, `room_id`, `tariff_type_id`,`hd_tariff_from`, `hd_tariff_to`, `hd_single_rate`, `hd_default_rate`, `thd_sunday`, `thd_monday`, `thd_thuesday`, `thd_wednesday`, `thd_thursday`, `thd_friday`, `thd_saturday`) VALUES
(1, 1, 1, '2019-01-05', '2019-01-10',100,200, 1, 1, 1, 1, 1, 1, 1),
(1, 2, 1, '2019-03-09', '2019-03-25',400,600, 1, 0, 0, 1, 0, 0, 0);
该方案是根据两个表中提供的房价信息显示适用于酒店的房价。通常,一个房间会有不同类型的价格,例如“合同价格”,“季节性价格”等,每种类型,酒店行政团队将提供适用的价格以及适用日期的日期范围。
当酒店行政团队想要指定某些特定日期的额外加息时,就会出现问题。此信息存储在riffit_hike_day表中,酒店管理团队可以在该表中指定要按基本费率应用加息的日期范围和日期(星期天,星期一等)。
完整条目完成后,系统将显示以下结果:
+-------+---------------+---------------+------------------+------------+------------+-------------+--------------+
| Sl No | Property Name | Room | Tariff Type | Date From | Date To | Single Rate | Default Rate |
+-------+---------------+---------------+------------------+------------+------------+-------------+--------------+
| 1 | Black Forest | Standard Room | Season Rates | 2019-01-01 | 2019-01-04 | 1000 | 2000 |
| 2 | Black Forest | Standard Room | Season Rates | 2019-01-05 | 2019-01-10 | 1100 | 2200 |
| 3 | Black Forest | Standard Room | Season Rates | 2019-01-11 | 2019-01-20 | 1000 | 2000 |
| 4 | Black Forest | Standard Room | Contracted Rates | 2019-02-06 | 2019-02-12 | 5000 | 10000 |
| 5 | Black Forest | AC Room | Season Rates | 2019-03-05 | 2019-03-09 | 8000 | 7000 |
| 6 | Black Forest | AC Room | Season Rates | 2019-03-10 | 2019-03-10 | 8400 | 8600 |
| 7 | Black Forest | AC Room | Season Rates | 2019-03-11 | 2019-03-12 | 8000 | 7000 |
| 8 | Black Forest | AC Room | Season Rates | 2019-03-13 | 2019-03-13 | 8400 | 8600 |
| 9 | Black Forest | AC Room | Season Rates | 2019-03-14 | 2019-03-16 | 8000 | 7000 |
| 10 | Black Forest | AC Room | Season Rates | 2019-03-17 | 2019-03-17 | 8400 | 8600 |
| 11 | Black Forest | AC Room | Season Rates | 2019-03-18 | 2019-03-19 | 8000 | 7000 |
| 12 | Black Forest | AC Room | Season Rates | 2019-03-20 | 2019-03-20 | 8400 | 8600 |
| 13 | Black Forest | AC Room | Season Rates | 2019-03-21 | 2019-03-23 | 8000 | 7000 |
| 14 | Black Forest | AC Room | Season Rates | 2019-03-24 | 2019-03-24 | 8400 | 8600 |
| 15 | Black Forest | AC Room | Season Rates | 2019-03-25 | 2019-04-10 | 8000 | 7000 |
+-------+---------------+---------------+------------------+------------+------------+-------------+--------------+
任何帮助将不胜感激。
答案 0 :(得分:0)
我知道答案有点晚了,但希望对您有所帮助。
首先,您需要确保在两个表'room_tariff'和'tariff_hike_day'
要找到它,可以使用下面给出的查询。
在 room_tariff 表中找到重复日期(重叠日期)
SELECT
a.*
FROM
`room_tariff` AS a
INNER JOIN `room_tariff` AS b
ON a.`id` != b.`id`
AND a.`room_id` = b.`room_id`
AND a.`tariff_type_id` = b.`tariff_type_id`
AND NOT (
(
a.`tariff_from` > b.`tariff_from`
AND a.`tariff_from` > b.`tariff_to`
)
OR (
a.`tariff_to` < b.`tariff_from`
AND a.`tariff_to` < b.`tariff_to`
)
)
GROUP BY a.`room_id`,
a.`tariff_type_id`,
a.`tariff_from`,
a.`tariff_to`
ORDER BY a.`room_id` ASC,
a.`tariff_type_id` ASC,
a.`tariff_from` ASC ;
在 tariff_hike_day 表中查找重复的日期(重叠的日期)
SELECT
a.*
FROM
`tariff_hike_day` AS a
INNER JOIN `tariff_hike_day` AS b
ON a.`id` != b.`id`
AND a.`room_id` = b.`room_id`
AND a.`tariff_type_id` = b.`tariff_type_id`
AND NOT (
(
a.`hd_tariff_from` > b.`hd_tariff_from`
AND a.`hd_tariff_from` > b.`hd_tariff_to`
)
OR (
a.`hd_tariff_to` < b.`hd_tariff_from`
AND a.`hd_tariff_to` < b.`hd_tariff_to`
)
)
GROUP BY a.`room_id`,
a.`tariff_type_id`,
a.`hd_tariff_from`,
a.`hd_tariff_to`
ORDER BY a.`room_id` ASC,
a.`tariff_type_id` ASC,
a.`hd_tariff_from` ASC ;
两个查询都应返回“零”行,以避免重叠。在这里,我加入了同一张桌子,并以相同的价格检查了同一房间的重叠日期。
This link will help you get more explanation
要获得预期的结果,我们可以在存储过程的帮助下进行以下操作。
DELIMITER $$
DROP PROCEDURE IF EXISTS `testprocedure`$$
CREATE PROCEDURE `testprocedure`()
BEGIN
DECLARE my_id,
my_room_id,
my_tariff_type_id,
my_hd_id BIGINT ;
DECLARE my_single_rate,
my_default_rate,
my_hd_single_rate,
my_hd_default_rate INT ;
DECLARE my_tariff_from,
my_tariff_to,
my_hd_tariff_from,
my_hd_tariff_to,
currentdate,
startdate,
stopdate DATE ;
DECLARE my_thd_sunday,
my_thd_monday,
my_thd_tuesday,
my_thd_wednesday,
my_thd_thursday,
my_thd_friday,
my_thd_saturday SMALLINT ;
DECLARE cur_done INTEGER DEFAULT 0 ;
DECLARE `should_rollback` BOOL DEFAULT FALSE;
DECLARE cur1 CURSOR FOR
SELECT
a1.*,
a2.id,
hd_tariff_from,
hd_tariff_to,
hd_single_rate,
hd_default_rate,
thd_sunday,
thd_monday,
thd_thuesday,
thd_wednesday,
thd_thursday,
thd_friday,
thd_saturday
FROM
`room_tariff` AS a1
LEFT JOIN `tariff_hike_day` a2
ON a1.`room_id` = a2.`room_id`
AND a1.`tariff_type_id` = a2.`tariff_type_id`
AND a2.`hd_tariff_from` != '0000-00-00'
AND NOT (
a1.`tariff_from` > a2.`hd_tariff_to`
OR a1.`tariff_to` < a2.`hd_tariff_from`
)
WHERE a1.tariff_from != '0000-00-00'
AND a1.`tariff_from` <= a1.`tariff_to`
ORDER BY a1.`room_id` ASC,
a1.`tariff_type_id` ASC,
a1.`tariff_from` ASC,
a2.`hd_tariff_from` ASC ;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET cur_done = 1 ;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET `should_rollback` = TRUE;
START TRANSACTION;
CREATE TABLE IF NOT EXISTS `room_rate_temp` (
`id` INT (11) UNSIGNED NOT NULL AUTO_INCREMENT,
`room_id` BIGINT (20) NOT NULL,
`tariff_type_id` BIGINT (20) NOT NULL,
`tariff_from` DATE NOT NULL,
`tariff_to` DATE NOT NULL,
`single_rate` INT (11) NOT NULL,
`default_rate` INT (11) NOT NULL,
`resultset_id` INT (11) UNSIGNED NOT NULL,
PRIMARY KEY (`id`)
) ENGINE = INNODB DEFAULT CHARSET = utf8 ;
SET @last_res_id := 0 ;
TRUNCATE TABLE room_rate_temp ;
OPEN cur1 ;
loop_matched_tables :
LOOP
FETCH cur1 INTO my_id,
my_room_id,
my_tariff_type_id,
my_tariff_from,
my_tariff_to,
my_single_rate,
my_default_rate,
my_hd_id,
my_hd_tariff_from,
my_hd_tariff_to,
my_hd_single_rate,
my_hd_default_rate,
my_thd_sunday,
my_thd_monday,
my_thd_tuesday,
my_thd_wednesday,
my_thd_thursday,
my_thd_friday,
my_thd_saturday ;
IF cur_done = 1 THEN
CLOSE cur1 ;
LEAVE loop_matched_tables ;
END IF ;
IF my_tariff_from <= my_tariff_to THEN
IF @last_res_id = my_id THEN
SELECT id,tariff_from FROM `room_rate_temp` WHERE `resultset_id` = my_id ORDER BY id DESC LIMIT 1 INTO @lastid,@last_tariff_from ;
SET my_tariff_from := @last_tariff_from ;
DELETE FROM room_rate_temp WHERE id = @lastid ;
END IF ;
IF my_hd_id IS NULL THEN
INSERT INTO room_rate_temp
VALUES
(
NULL,
my_room_id,
my_tariff_type_id,
my_tariff_from,
my_tariff_to,
my_single_rate,
my_default_rate,
my_id
) ;
ELSE
IF ( my_hd_tariff_from <= my_hd_tariff_to ) THEN
SET startdate := my_tariff_from ;
SET currentdate := my_tariff_from ;
SET stopdate := my_tariff_to ;
SET @insflag := 1 ;
SET @last_insid := @last_hike_flag := @hiketablecovered := @splitonce := 0 ;
WHILE
currentdate <= stopdate DO
SET @my_repeat_col_name := DAYNAME(currentdate) ;
SET @hd_single_rate := my_single_rate ;
SET @hd_default_rate := my_default_rate ;
SELECT
CASE
@my_repeat_col_name
WHEN 'Sunday'
THEN my_thd_sunday
WHEN 'Monday'
THEN my_thd_monday
WHEN 'Tuesday'
THEN my_thd_tuesday
WHEN 'Wednesday'
THEN my_thd_wednesday
WHEN 'Thursday'
THEN my_thd_thursday
WHEN 'Friday'
THEN my_thd_friday
WHEN 'Saturday'
THEN my_thd_saturday
ELSE NULL
END AS mydate INTO @hikeapplicable ;
IF ( currentdate BETWEEN my_hd_tariff_from AND my_hd_tariff_to ) THEN
IF ( @last_hike_flag != @hikeapplicable ) THEN
SET @insflag := 1 ;
SET @last_hike_flag := @hikeapplicable ;
SET @splitonce := 1 ;
IF ( @hikeapplicable = 1 ) THEN
SET @hd_single_rate := my_single_rate + my_hd_single_rate ;
SET @hd_default_rate := my_default_rate + my_hd_default_rate ;
END IF ;
END IF ;
SET @hiketablecovered := 1;
ELSEIF ( (currentdate > my_hd_tariff_to) AND ( @hiketablecovered = 1 ) AND (@splitonce = 1) ) THEN
IF(@last_hike_flag = 1) THEN
SET @insflag := 1;
END IF ;
SET @hiketablecovered := @splitonce := 0 ;
END IF ;
IF (@insflag = 1) THEN
INSERT INTO room_rate_temp VALUES ( NULL, my_room_id, my_tariff_type_id, currentdate, currentdate, @hd_single_rate, @hd_default_rate, my_id );
SET @last_insid := LAST_INSERT_ID() ;
SET @insflag := 0 ;
ELSE
UPDATE room_rate_temp SET tariff_to = currentdate WHERE id = @last_insid;
END IF ;
SET currentdate = ADDDATE(currentdate, INTERVAL 1 DAY) ;
END WHILE ;
END IF ;
END IF ;
SET @last_res_id := my_id;
END IF ;
END LOOP loop_matched_tables ;
SET @count:=0;
SELECT (@count:=@count+1) AS `Sl No`, d.name AS `Property Name`, c.room_name AS Room, b.tt_tariff_name AS `Tariff Type`, a.tariff_from AS `Date From`, a.tariff_to AS `Date To`, a.single_rate AS `Single Rate`, a.default_rate AS `Default Rate`
FROM room_rate_temp AS a INNER JOIN ms_tariff_type AS b ON a.tariff_type_id = b.tt_id INNER JOIN ms_property_room AS C
ON a.room_id = c.id INNER JOIN ms_property AS d ON c.property_id = d.id;
IF `should_rollback` THEN
ROLLBACK;
ELSE
COMMIT;
END IF;
END$$
DELIMITER ;
在此过程中,
为了存储结果,我创建了一个临时表,该表将一直存在直到下一次查询,以便您可以随时获取最后一个结果。
首先,我加入了关税和加价表,以查找相似日期范围内的匹配项。
然后循环查询结果并在适用加息时中断行。