Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 动态更新表并重新排列记录_Mysql - Fatal编程技术网

Mysql 动态更新表并重新排列记录

Mysql 动态更新表并重新排列记录,mysql,Mysql,我有一张桌子,让我们说: **tblHotel** id start_date end_date rate 现在,我想编写更新日期范围记录的过程,例如,我有数据: id start_date end_date rate 1 2016/01/01 2016/01/10 10 2 2016/01/11 2016/01/20 50 现在,若一个新的日期范围和费率来自供应商,我想更新表格记录,就像新的范围一样

我有一张桌子,让我们说:

**tblHotel**
    id
    start_date
    end_date
    rate
现在,我想编写更新日期范围记录的过程,例如,我有数据:

id   start_date     end_date     rate
1    2016/01/01     2016/01/10   10
2    2016/01/11     2016/01/20   50 
现在,若一个新的日期范围和费率来自供应商,我想更新表格记录,就像新的范围一样

  start_date   end_date     rate
  2016/01/05   2016/01/12   100
现在更新的记录应如下所示:

id   start_date     end_date     rate
1    2016/01/01     2016/01/04   10
2    2016/01/05     2016/01/12   100
3    2016/01/13     2016/01/20   50 
质疑

insert into tbl_Hotel(start_date, end_date, rate)
        select $start_date, $end_date, $rate
        from dual
        where not exists (select 1
                          from tbl_Hotel h
                          where h.start_date <= $end_date and h.end_date >= $start_date
                         );

首先检查是否可以在不破坏一致性的情况下进行更新

然后在一个事务中运行以下语句:

-定义新的条目数据 设置开始日期:=“2016-01-05”; 在结束日期设置:=“2016-01-12”; 设置@速率:=100; -查找插入新行的位置 在@new_id中选择h.id 来自tbl_h酒店 其中h.start\u date>@start\u date; -为新行留出空间 更新tbl_酒店h 设置h.id=h.id+1 其中h.id>=@new\u id; -查找将位于新行之前的行 在@prev_id中选择maxh.id 来自tbl_h酒店 其中h.开始日期<@开始日期; -查找新行后面的行 选择minh.id进入@next\u id 来自tbl_h酒店 其中h.start\u date>@start\u date; -更新上一行的结束日期 更新tbl_酒店h 设置h.end_日期=@start_日期-间隔1天 其中h.id=@prev_id; -更新下一行的开始日期 更新tbl_酒店h 设置h.start\u date=@end\u date+间隔1天 其中h.id=@next_id; -插入新行 插入tbl_酒店'id','start_date','end_date','rate` 值@new\u id、@start\u date、@end\u date、@rate;
这可能不是完全正确的-和/或它可能是一个小部分太做作-但我相信它沿着正确的路线

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,start_date DATE NOT NULL UNIQUE
,end_date DATE NOT NULL
,rate INT NOT NULL
);

INSERT INTO my_table VALUES
(1,'2016-01-01','2016-01-10',10),
(2,'2016-01-11','2016-01-20',50); 

INSERT INTO my_table
SELECT y.id
     , COALESCE(GREATEST(x.start_date,y.start_date),x.start_date) start_date
     , COALESCE(LEAST(x.end_date,y.end_date),x.end_date) end_date
     , x.rate
  FROM 
     ( SELECT a.start_date
            , MIN(COALESCE(b.start_date,a.end_date)) end_date
            , a.rate
         FROM 
            ( SELECT LEAST(start_date,'2016-01-05') start_date, LEAST(end_date,'2016-01-04') end_date, rate FROM my_table
              UNION
              SELECT GREATEST(start_date,'2016-01-13') start_date, GREATEST(end_date,'2016-01-12') end_date, rate FROM my_table
              UNION
              SELECT '2016-01-05','2016-01-12',100
            ) a
         LEFT 
         JOIN
            ( SELECT LEAST(start_date,'2016-01-05') start_date, LEAST(end_date,'2016-01-04') end_date,rate FROM my_table
              UNION
              SELECT GREATEST(start_date,'2016-01-13') start_date, GREATEST(end_date,'2016-01-12') end_date,rate FROM my_table
              UNION
              SELECT '2016-01-05','2016-01-12',100
            ) b
           ON b.start_date < a.end_date
          AND b.end_date > a.start_date
          AND a.start_date < b.start_date
          AND b.rate <> a.rate
        GROUP
           BY a.start_date
            , a.rate
       HAVING end_date >= start_date
     ) x
  LEFT
  JOIN my_table y
    ON y.start_date < x.end_date
   AND y.end_date > x.start_date
   AND y.rate = x.rate
    ON DUPLICATE KEY UPDATE start_date = COALESCE(GREATEST(x.start_date,y.start_date),x.start_date) 
                          , end_date = COALESCE(LEAST(x.end_date,y.end_date),x.end_date); 

SELECT * FROM my_table;
+----+------------+------------+------+
| id | start_date | end_date   | rate |
+----+------------+------------+------+
|  1 | 2016-01-01 | 2016-01-04 |   10 |
|  2 | 2016-01-13 | 2016-01-20 |   50 |
|  3 | 2016-01-05 | 2016-01-12 |  100 |
+----+------------+------------+------+
请注意,ID不会移动以适应修改后的日期。那是故意的