MySQL Querying Aggregate of Non Overlapping Dates

China☆狼群 提交于 2019-11-28 06:49:03

问题


Let's assume that the following data stream is given:

CREATE TABLE reservation (
  id bigint(20),
  start_datetime DATETIME NOT NULL,
  end_datetime DATETIME
);

1. The First Data Stream

INSERT INTO reservation (id, start_datetime, end_datetime) VALUES
(1, '2015-05-01 00:00:00', '2015-05-03 00:00:00'),
(2, '2015-05-02 00:00:00', '2015-05-05 00:00:00'),
(3, '2015-05-03 00:00:00', '2015-05-04 00:00:00'),
(4, '2015-05-05 00:00:00', '2015-05-07 00:00:00');

For the first insert values id = 1, 2, 3, and 4. I need to get the "Total Reservation Index". The expected result will be:

+------+-------------------------+---------------------+---------------------+
| id   | Total Reservation Index | start_datetime      | end_datetime        |
+------+-------------------------+---------------------+---------------------+
|    1 |                      2  | 2015-05-01 00:00:00 | 2015-05-03 00:00:00 |
|    4 |                      2  | 2015-05-05 00:00:00 | 2015-05-07 00:00:00 |
+------+-------------------------+---------------------+---------------------+

2. The Second Data Stream

INSERT INTO reservation (id, start_datetime, end_datetime) VALUES
(5, '2015-05-04 00:00:00', null),
(6, '2015-05-02 00:00:00', null),
(7, '2015-05-05 00:00:00', null),
(8, '2015-05-01 00:00:00', null);

You will notice that end_datetime is NULL. The business logic for table reservation means, the reservation is opened forever. So, by using the same query like the first data stream, it should result as follow:

+------+-------------------------+---------------------+---------------------+
| id   | Total Reservation Index | start_datetime      | end_datetime        |
+------+-------------------------+---------------------+---------------------+
|    1 |                      2  | 2015-05-01 00:00:00 | 2015-05-03 00:00:00 |
|    5 |                      5  | 2015-05-04 00:00:00 | 2015-05-08 00:00:00 |
+------+-------------------------+---------------------+---------------------+

Notice that the id = 4 is changed to id = 5. Thus, the total index if we do SUM operation for "Total Reservation Index" column is 7 (or 2 + 5).

3. The Third Data Stream

INSERT INTO reservation (id, start_datetime, end_datetime) VALUES
(9, '2015-05-04 00:00:00', '2015-05-04 00:00:00'),
(10, '2015-05-05 00:00:00', '2015-05-07 00:00:00'),
(11, '2015-05-01 00:00:00', '2015-05-07 00:00:00');

For the third data stream, we will use the same query.. the expected result will be the same result as the second data stream. It will return 2 rows => id 1 and 5.

4. The Fourth Data Stream

INSERT INTO reservation (id, start_datetime, end_datetime) VALUES
(12, '2015-05-07 00:00:00', null);

In the forth data stream, it will have the same result like the second data stream. It will return 2 rows => id 1 and 5.

Current Attempt

My current attempt is by using this

select id, datediff('2015-05-08', start_datetime) as 'Total Reservation Index', start_datetime, end_datetime from reservation where start_datetime < end_datetime or end_datetime is null and start_datetime >= '2015-05-01' and end_datetime <= '2015-05-08' order by start_datetime asc;

EDIT: Sorry for the confusion of '2015-05-08'. '2015-05-08' comes from the end filter date. Like I ask in the question below. It does have filter start_date and end_date. Hence, the value of '2015-05-08' intended to trick/replace the NULL value in end_datetime column. In addition, for any given NULL data in end_datetime column it will replace the end filter date. The end filter date could be '2015-05-10' or '2015-05-11' but of course it will expect different query results.

However, the query above did not go as expected. Since I need to exclude the overlapping dates and also I need to filter based on start_datetime and end_datetime.

To illustrate the overlapping dates, I have included the images below.

The YELLOW block represents the data has proper datetime value in end_datetime column.

The ORANGE block represents the data has NULL value in end_datetime column.

Now, What would the SQL to achieve the expected result for the first, second, third, and fourth data stream? (Note: It must be the same SQL query for all data streams. Since it does not make sense for every data stream to use different SQL query)

来源:https://stackoverflow.com/questions/30378663/mysql-querying-aggregate-of-non-overlapping-dates

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