1

MySQL プロシージャを使用して、ショップの営業時間内にオープン日を取得しています。

私のショップは、配達/集荷 (delivery_type) の営業時間が異なります。さらに、ショップが非常に忙しい場合に備えて、現在の時間を増やすために整数パラメーター (オフセット) を使用しています。オフセットは当日のみ考慮されなければなりません。

営業時間は、曜日 (1-7) に一致する 1 つのレコードとして、テーブル *shop_hours* で定義されます。柔軟性を追加するために、特別な日付用に別のテーブル *shop_hours_special* を用意しています。このテーブルは、shop_hours で定義されている開店時間と閉店時間に優先します。*shop_hours_special* は年間通算日として定義されます。

私の問題:

  1. CALL nextDate(2, 9999999);

これは 2012-12-16 (今日の UTC+1) を返しますが、offset パラメーターが非常に大きいため、次の開始日 (2012-12-17 月曜日など) にプッシュする必要があります。

  1. CALL nextDate(1,0);

ショップの営業時間が今日であるが、まだ開店時間になっていない場合は、次の営業日に返されますが、実際には今日の日付が返されます。

私が間違っていることで、誰かが助けてくれますか?


PHP 関数:

public function get_next_open_date($delivery_type, $offset = 0) {

    $sql = 'CALL nextDate('.$delivery_type.','.$offset.');';
    $date = $this->app['db']->fetchAssoc($sql);

    return date('Y-m-d', strtotime($date['final_date']));
}

MySQL 手順:

DROP PROCEDURE IF EXISTS `nextDate`;
DELIMITER $$
CREATE PROCEDURE `nextDate`(IN dType TINYINT(3), IN dOffset INT)
BEGIN

    DECLARE CURTIME TIME;
    DECLARE final_date DATE;
    DECLARE match_found, closed_day BOOLEAN;
    DECLARE dYear, dWeek, dayYear, dayWeek, contor INT;

    SET contor = 0;
    SET match_found = TRUE;
    SET dayYear = DAYOFYEAR(NOW());
    SET dayWeek = WEEKDAY(NOW()) + 1;
    SET dYear = -1;
    SET dWeek = -1;
    SET CURTIME = ADDTIME(TIME(NOW()),SEC_TO_TIME(dOffset));

    WHILE match_found DO

        SET closed_day = FALSE;
        IF contor = 0 THEN
            SELECT IFNULL(a.day_of_year, -1), IF(open_time = MAKETIME(0,0,0) AND close_time = MAKETIME(0,0,0), TRUE, FALSE) INTO dYear, closed_day
                FROM shop_hours_special a
                WHERE a.`type` = dType AND a.day_of_year = dayYear
                    AND (CURTIME BETWEEN a.open_time AND a.close_time OR (open_time = MAKETIME(0,0,0) AND close_time = MAKETIME(0,0,0)));       

            SELECT IFNULL(b.day_of_week, -1) INTO dWeek
                FROM shop_hours b
                WHERE b.`type` = dType AND b.day_of_week = dayWeek AND (b.open_time != MAKETIME(0,0,0) OR b.close_time != MAKETIME(0,0,0)) AND CURTIME BETWEEN b.open_time AND b.close_time ;

        ELSE
            SELECT IFNULL(a.day_of_year, -1), IF(open_time = MAKETIME(0,0,0) AND close_time = MAKETIME(0,0,0), TRUE, FALSE) INTO dYear, closed_day
                FROM shop_hours_special a
                WHERE a.`type` = dType AND a.day_of_year = dayYear;

            SELECT IFNULL(b.day_of_week, -1) INTO dWeek
                FROM shop_hours b
                WHERE b.`type` = dType AND b.day_of_week = dayWeek AND (b.open_time != MAKETIME(0,0,0) OR b.close_time != MAKETIME(0,0,0));
        END IF;

        IF closed_day THEN
            SET dYear = -1;
            SET dWeek = -1;
        END IF;     

        IF dYear != -1 THEN
            SET final_date = MAKEDATE(YEAR(NOW()), dYear);
            SET match_found = FALSE;

        ELSEIF dWeek != -1 THEN

            SET final_date = NOW() + INTERVAL contor DAY;
            SET match_found = FALSE;

        ELSE
            SET contor = contor + 1;
            SET dayYear = DAYOFYEAR(NOW() + INTERVAL contor DAY);
            SET dayWeek = WEEKDAY(NOW() + INTERVAL contor DAY) + 1; 

        END IF;

    END WHILE;

    SELECT final_date;

END$$

DELIMITER ;

サンプルデータ:

CREATE TABLE `shop_hours` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `shop_id` int(11) unsigned NOT NULL,
  `type` tinyint(3) NOT NULL DEFAULT '1',
  `day_of_week` int(11) NOT NULL,
  `open_time` time NOT NULL,
  `close_time` time NOT NULL,
  PRIMARY KEY (`id`),
  KEY `shop_id` (`shop_id`),
  CONSTRAINT `shop_hours_ibfk_1` FOREIGN KEY (`shop_id`) REFERENCES `shops` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `shop_hours` (`id`, `shop_id`, `type`, `day_of_week`, `open_time`, `close_time`)
VALUES
    (1,1,1,1,'09:30:00','20:00:00'),
    (2,1,1,2,'09:30:00','20:00:00'),
    (3,1,1,3,'09:30:00','20:00:00'),
    (4,1,1,4,'09:30:00','20:00:00'),
    (5,1,1,5,'09:30:00','20:00:00'),
    (6,1,1,6,'09:30:00','20:00:00'),
    (7,1,1,7,'11:00:00','20:00:00'),
    (8,1,2,1,'11:30:00','12:30:00'),
    (9,1,2,2,'11:30:00','12:30:00'),
    (10,1,2,3,'11:30:00','12:30:00'),
    (11,1,2,4,'11:30:00','12:30:00'),
    (12,1,2,5,'11:30:00','12:30:00'),
    (13,1,2,6,'00:00:00','00:00:00'),
    (14,1,2,7,'00:01:00','23:00:00');

CREATE TABLE `shop_hours_special` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `shop_id` int(11) unsigned NOT NULL,
  `type` tinyint(3) NOT NULL DEFAULT '1',
  `day_of_year` int(11) NOT NULL,
  `open_time` time NOT NULL,
  `close_time` time NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique` (`shop_id`,`type`,`day_of_year`),
  KEY `shop_id` (`shop_id`),
  CONSTRAINT `shop_hours_special_ibfk_1` FOREIGN KEY (`shop_id`) REFERENCES `shops` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `shop_hours_special` (`id`, `shop_id`, `type`, `day_of_year`, `open_time`, `close_time`)
VALUES
    (1,1,1,1,'00:00:00','00:00:00'),
    (2,1,1,92,'00:00:00','00:00:00'),
    (3,1,1,96,'00:00:00','00:00:00'),
    (4,1,1,97,'00:00:00','00:00:00'),
    (5,1,1,99,'00:00:00','00:00:00'),
    (6,1,1,100,'00:00:00','00:00:00'),
    (7,1,1,125,'00:00:00','00:00:00'),
    (8,1,1,138,'00:00:00','00:00:00'),
    (9,1,1,148,'00:00:00','00:00:00'),
    (10,1,1,149,'00:00:00','00:00:00'),
    (11,1,2,1,'00:00:00','00:00:00'),
    (12,1,2,92,'00:00:00','00:00:00'),
    (13,1,2,96,'00:00:00','00:00:00'),
    (14,1,2,97,'00:00:00','00:00:00'),
    (15,1,2,99,'00:00:00','00:00:00'),
    (16,1,2,100,'00:00:00','00:00:00'),
    (17,1,2,125,'00:00:00','00:00:00'),
    (18,1,2,138,'00:00:00','00:00:00'),
    (19,1,2,148,'00:00:00','00:00:00'),
    (20,1,2,149,'00:00:00','00:00:00');
4

0 に答える 0