Transform Dates into Date Range in MYSQL---how to handle gaps in the dates

我怕爱的太早我们不能终老 提交于 2019-12-23 05:19:55

问题


I am looking for a help in transforming below data into the required output. We have data at Item,LOC DAY level data which needs to be transformed to Item,Loc Date Range to reduce the number of records in the table and for other requirements.

Item        LOC  RP_DATE    RP_IND   
1003785256  543 2016-11-05  Y
1003785256  543 2016-11-06  Y
1003785256  543 2016-11-07  Y
1003785256  543 2016-11-09  Y
1003785256  543 2016-11-10  Y
1003790365  150 2016-11-05  Y
1003797790  224 2016-11-05  Y
1003797790  224 2016-11-06  Y
1003797790  224 2016-11-07  Y
1003797790  224 2016-11-08  Y

Required Output:

Item        LOC  RP_ST_DATE    RP_END_DATE   
1003785256  543 2016-11-05   2016-11-07
1003785256  543 2016-11-09   2016-11-10
1003790365  150 2016-11-05   2016-11-05
1003797790  224 2016-11-05   2016-11-08

回答1:


This approach is for MySQL. It uses a combination variables within an ordered subquery to establish a common starting date for each "range". The CROSS JOIN is used just to initialize the variables, it does not alter the number of rows. Once the common starting date is established then it becomes a simple group by query in the outer query.

SELECT Item, LOC, RP_IND, dr_begin, MAX(RP_DATE) dr_end
FROM (
  SELECT
         mytable.*
       , @fin := CONVERT(IF(@item<=>item AND @loc<=>loc AND DATEDIFF(rp_date, @d)=1, @fin, rp_date), DATE) AS dr_begin
       , @item := item
       , @loc := loc
       , @d := rp_date
  FROM     mytable CROSS JOIN (SELECT @item:=NULL, @loc:=NULL, @d:=NULL, @fin := NULL) AS init
  ORDER BY item, loc, rp_date
  ) d
GROUP BY  Item, LOC, RP_IND, dr_begin
;

+----+------------+-----+--------+------------+---------------------+
|    |    Item    | LOC | RP_IND |  dr_begin  |       dr_end        |
+----+------------+-----+--------+------------+---------------------+
|  1 | 1003785256 | 543 | Y      | 2016-11-05 | 07.11.2016 00:00:00 |
|  2 | 1003785256 | 543 | Y      | 2016-11-09 | 10.11.2016 00:00:00 |
|  3 | 1003790365 | 150 | Y      | 2016-11-05 | 05.11.2016 00:00:00 |
|  4 | 1003797790 | 224 | Y      | 2016-11-05 | 08.11.2016 00:00:00 |
+----+------------+-----+--------+------------+---------------------+

Note <=> returns 1 if both operands are NULL

See the query working at: http://rextester.com/SEYG96251

#drop table mytable;

CREATE TABLE mytable(
   Item    INTEGER  NOT NULL
  ,LOC     INTEGER  NOT NULL
  ,RP_DATE DATE  NOT NULL
  ,RP_IND  VARCHAR(1) NOT NULL
);
INSERT INTO mytable(Item,LOC,RP_DATE,RP_IND) VALUES (1003785256,543,'2016-11-05','Y');
INSERT INTO mytable(Item,LOC,RP_DATE,RP_IND) VALUES (1003785256,543,'2016-11-06','Y');
INSERT INTO mytable(Item,LOC,RP_DATE,RP_IND) VALUES (1003785256,543,'2016-11-07','Y');
INSERT INTO mytable(Item,LOC,RP_DATE,RP_IND) VALUES (1003785256,543,'2016-11-09','Y');
INSERT INTO mytable(Item,LOC,RP_DATE,RP_IND) VALUES (1003785256,543,'2016-11-10','Y');
INSERT INTO mytable(Item,LOC,RP_DATE,RP_IND) VALUES (1003790365,150,'2016-11-05','Y');
INSERT INTO mytable(Item,LOC,RP_DATE,RP_IND) VALUES (1003797790,224,'2016-11-05','Y');
INSERT INTO mytable(Item,LOC,RP_DATE,RP_IND) VALUES (1003797790,224,'2016-11-06','Y');
INSERT INTO mytable(Item,LOC,RP_DATE,RP_IND) VALUES (1003797790,224,'2016-11-07','Y');
INSERT INTO mytable(Item,LOC,RP_DATE,RP_IND) VALUES (1003797790,224,'2016-11-08','Y');


来源:https://stackoverflow.com/questions/45023270/transform-dates-into-date-range-in-mysql-how-to-handle-gaps-in-the-dates

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!