SQL 2日期范围重叠日计数

时间:2017-04-01 20:20:46

标签: mysql sql datetime

我有一个简单的网络应用程序,用户登录并分配一个日期范围,当他们可以免费提供某些休息日,以及一个日期范围,当他们想要休息几天。这采取请求的形式。用户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 中运行。非常感谢。

1 个答案:

答案 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;