Mysql程序选择下一个日期

时间:2012-12-15 23:39:19

标签: mysql stored-procedures

我正在使用MySQL程序在商店开放时间内获取开放日期。

我的商店有不同的开放时间(发货/提货)。另外我使用整数参数(偏移量),以增加当前时间,因此店铺真的很忙。只能在当天考虑抵消。

开放时间在表* shop_hours *中定义,作为与星期几(1-7)匹配的一条记录。为了增加一些灵活性,我有一个单独的表* shop_hours_special *用于特殊日期。该表格否决了shop_hours中定义的任何开启/关闭时间。 * shop_hours_special *定义为一年中的某一天。

我的问题:

  1. CALL nextDate(2,9999999);
  2. 这将返回2012-12-16(今天是UTC + 1),但是偏移参数太高了,它应该推到下一个开放日期,例如星期一,2012-12-17。

    1. CALL nextDate(1,0);
    2. 如果商店今天有营业时间,但尚未达到营业时间,则会在下一个营业日返回,但真的应该在今天返回。

      有人可以帮忙,我做错了吗?


      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');
      

0 个答案:

没有答案