Я знаю, немного поздно, чтобы ответить, но надеюсь, что это поможет вам.
Прежде всего, вам нужно убедиться, что не существует перекрывающихся дат для одной и той же комнаты с одинаковым тарифом на обеих таблицах 'room_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 ;
Поиск повторяющихся дат (перекрывающихся дат) в Tar_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 ;
Обазапросы должны возвращать строки 'ZERO', чтобы избежать перекрытия.Здесь я присоединился к той же таблице и проверил перекрывающиеся даты для той же комнаты с тем же тарифом.
Эта ссылка поможет вам получить более подробное объяснение
Чтобы получить ожидаемый результат, мы можем сделать это с помощью хранимой процедуры следующим образом.
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 ;
В этой процедуре
Для сохранения результата я создал одну временную таблицу и будет существовать до следующего запроса, чтобы вы могли получить последний результат в любое время.
Сначала я присоединился к таблице тарифов и походов, чтобы найти совпадения для аналогичного диапазона дат.
Затем зациклил результат запроса и разбил строки, когда подход был применим.