简体   繁体   中英

Find if given date range inside another date range in MySQL

I have a price_table, that has two columns: start_date and end_date (for promotional prices).

I'm trying to create a query that will check whether or not the given date range doesn't fall under another one that already exists.

I've been trying to use this query:

SELECT *
FROM tbl_preco
WHERE isActive = 1 AND (start_date between '2014-12-11 15:45:00' AND '2014-12-13 11:45:00'
        OR end_date between '2014-12-11 15:45:00' AND '2014-12-13 11:45:00')

The problem is:

There's a promotional price from 2014-12-10 15:30:00 to 2014-12-13 14:30:00 , so neither of both BETWEEN instructions are catching it, even though the given range is in fact inside the range in the DB.

                   |------GIVEN RANGE-------|
       |-------- RANGE IN DB --------|

The example above should be returned as TRUE, and the application will tell the user that there's already a promotional price within the given range.

It sounds like you want any promotional sale that is active during the range. In that case, you don't need to check that the start dates and end dates exist in the range, which is what you are doing now. You simply need to check that the start date happened before the range is closed, and then that the end date happened after the range opened. Hope that makes sense?

SELECT *
FROM tbl_preco
WHERE isActive = 1 
AND start_date < '2014-12-13 11:45:00' 
AND end_date > '2014-12-11 15:45:00';

A simple condition to find out if two segments [a, b] and [c, d] intersect each other is (ad)*(bc) <= 0 . It covers all the situations, when one date range (segment) only starts or only ends during the other and also when one of the is completely included into the other.

In order to implement this in MySQL using dates you need to convert them to numbers (Unix timestamps):

SELECT *
FROM tbl_preco
WHERE isActive = 1
   AND (UNIX_TIMESTAMP(start_date) - UNIX_TIMESTAMP('2014-12-11 15:45:00'))
     * (UNIX_TIMESTAMP(end_date) - UNIX_TIMESTAMP('2014-12-13 11:45:00')) <= 0
;

When the product is 0 the date ranges either one is included into the other (start together or end together) or one of them starts exactly when the other ends.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM