MySql 检查日期范围是否重叠

MySql check if the dates range overlaps

+----+------------+---------------------+---------------------+---------+----------+
| id | percentage | from_date           | to_date             | type_id | tag      |
+----+------------+---------------------+---------------------+---------+----------+
|  1 |      10.00 | 2022-04-01 00:00:01 | 2022-04-05 23:59:59 |       1 | discount |
|  2 |      10.00 | 2022-04-06 00:00:01 | 2022-04-10 23:59:59 |       1 | uplift   |
|  3 |      10.00 | 2022-04-12 00:00:01 | 2022-04-15 23:59:59 |       1 | discount |
|  4 |      10.00 | 2022-04-20 00:00:01 | 2022-04-25 23:59:59 |       1 | uplift   |
+----+------------+---------------------+---------------------+---------+----------+

我正在尝试在 php 中创建一个函数,供用户创建 discount/uplift 价格。用户可以 select 起始日期和截止日期选择器。

现在,如果 selected 日期范围落在现有范围之间,我想限制用户创建 discount/uplift。

鉴于上述table,2022-04-01至2022-04-05和2022-04-12和2022-04-15的产品有折扣。因此用户无法为此范围创建任何 discount/uplift。

如上所述,2022-04-06 至 2022-04-10 和 2022-04-20 至 2022-04-25 之间的价格有所上涨,用户无法创建任何 discount/uplift对于这个范围。

SELECT * FROM `discounts` WHERE type_id = 1 AND (`from_date` <= $fromDate AND `to_date` >= $toDate);

SELECT * FROM discounts WHERE type_id = 1 AND '$fromDate' BETWEEN from_date AND to_date

SELECT * FROM discounts WHERE type_id = 1 AND '$toDate' BETWEEN from_date AND to_date

以上所有查询都有效。

但是在2022-04-11 00:00:002022-04-11 23:59:592022-04-16 00:00:002022-04-19 23:59:59

之间有一个window创建discount/uplift

有什么方法可以检查以上条件吗

编辑

我的问题是: 我如何验证用户输入 fromDate 作为 2022-04-16toDate 作为 2022-04-18,因为它是一个有效的日期范围,不属于 [=48] 中的任何范围=].因此用户可以在此范围内创建记录。

你可以这样检查:

SELECT * 
FROM `discounts` 
WHERE type_id = 1 
  AND `from_date` <= $toDate AND `to_date` >= $fromDate;

对于 $fromDate = '2022-04-11 00:00:00'$toDate = '2022-04-11 23:59:59' 查询将 return 没有任何内容,这意味着此日期时间间隔可用。

参见demo

您可以根据条件插入数据。以下查询中的 CTE 模拟了相关参数的来源

insert into tbl(id, percentage, from_date, to_date, type_id, tag )
with params as( 
   select timestamp '2022-04-16 00:00:01' fromDate, timestamp  '2022-04-18 00:00:01'  toDate
)
select 5, 11 ,fromDate, toDate, 1, 'discount'
from params p
where not exists(
  select 1 
  from tbl t
  where type_id = 1 and p.fromDate < t.to_Date  and t.from_Date < p.toDate)