我有一个简单的网络应用程序,用户登录并分配一个日期范围,当他们可以免费提供某些休息日,以及一个日期范围,当他们想要休息几天。这采取请求的形式。用户A提供“Jan 01-Jan31”并希望“May 01-May31”。
现在,用户B提出了一个请求,他们在5月份提出要求,也要求1月份。在此示例中,请求匹配。
Requests Table
--------------
"User A", "20170101", "20170131", "20170501", "20170531"
"User B", "20170501", "20170531", "20170101", "20170131"
然而,我需要它比这复杂一点。用户可能不会提供或想要整个月,而是特定的日期范围,例如:
用户A提供Jan01-Jan31但需要May20-May27
用户B提供5月15日至5月31日但希望Jan01-Jan05
在该示例中,它们也匹配,但是我需要计算每个请求与另一个请求重叠的天数,并且只有当重叠数量> = X天时,请求才会匹配(比如说应用程序集常量为4天)。
因此,每个请求再次相互联合,(将每个请求与每个其他请求进行比较),并且需要重叠日计数来检查匹配。
我发现这个公式可以提供 重叠,但我似乎也无法返回日期计数:
where not (t1.startdate > t2.endate or t1.enddate < t2.startdate)
请参阅此处的SqlFiddle:Fiddle
-- DateGivingFrom, DateGivingTo
-- DateWantFrom, DateWantTo
Create table t (Id int, uid varchar(6),
dgf date, dgt date,
Dwf date, dwt date);
Insert into t values (1,"Human1","20170101","20170131","20170501","20170507");
Insert into t values (2,"Human2","20170501","20170531","20170120","20170125");
Select *, (select count(*) from t
where not (v.dgf > t.dwt or v.dgt < t.dwf) )
as DatesOverlap,
("?") as OverlapDayCount
from t as v ;
请注意
每个用户提交请求时会有数百个用户,而且我也不会在每次用户提交请求时进行此计算,因为它可能非常密集。相反,我将有一个运行“检查器”的服务来执行此功能(因为它将根据结果设置通知,发送电子邮件等)
这将基于 php 在 mysql 中运行。非常感谢。
答案 0 :(得分:2)
基本理念是自我加入。我不确定你真正想要计算什么。以下计算两个时期的重叠:“g”到“w”然后“w”到“g”。
select t1.*, t2.*,
datediff(least(t1.dgt, t2.dwt) greatest(t1.dgf, t2.dwf)) as gw_overlap,
datediff(least(t2.dgt, t1.dwt) greatest(t2.dgf, t1.dwf)) as wg_overlap;
from t t1 join
t t2
on t1.dgf <= t2.dwt and t1.dgt >= t2.dwf and -- t1 "g" overlaps t2 "w"
t2.dgf <= t1.dwt and t2.dgt >= t1.dwf and
t1.uid <> t2.uid;