如何在MySQL和PHP中检查给定的日期周期在两个日期之间


How to check given date period is between two dates in MySQL and PHP

我有员工的旅行史。我想检查特定月份,他是在外站(在外面旅行)还是在办公室,以计算旅行小时数。只是我们正在维护旅行数据库,因为我们输入了员工姓名,客户所在地旅行以及旅行日期和返回日期。

一名员工具有以下数据:

  • 旅行日期: '2015-08-29' (29th Aug 2015)
  • 返回日期: '2015-11-06' (2015年11月6日)

所以在这里,我想检查一下十月份,所有不在办公室的员工。显然这个人应该属于这一类,但我无法得到他。
我也直接在MySQL工作台中尝试,但没有得到结果。

我的原始PHP代码:

// $req['date_start'] = '2015-10-01'
// $req['date_end'] = '2015-10-31'
$employeeTravel = new EmployeeTravelRecord();
$TravelEntryList = $employeeTravel->Find("(travel_date between ? and ? or  return_date between ? and ? )",array($req['date_start'], $req['date_end'],$req['date_start'], $req['date_end']));
$startdate = $req['date_start'];
$enddate = $req['date_end'];
foreach($TravelEntryList as $Travelentry){
    $key = $Travelentry->employee;  
    if($startdate >= $Travelentry->travel_date)
    {
        $firstdate = $startdate;
    }
    else
        $firstdate = $Travelentry->travel_date;
    if($enddate <= $Travelentry->return_date )
    {
        $lastdate = $enddate;
    }
    else
        $lastdate = $Travelentry->return_date;
    $holidays = $this->getholidays($firstdate,$lastdate);
    $totalhours = $this->getWorkingDays($firstdate,$lastdate,$holidays); //It returns in total time of outstation in hours excluding company holidays
    $amount = $totalhours;
    if(isset($TravelTimeArray[$key])){
        $TravelTimeArray[$key] += $amount;
    }else{
        $TravelTimeArray[$key] = $amount;
    }
}

但是我的输入数据不会检索该特定员工记录,因为旅行日期和返回日期都不在我的输入日期中。

MySQL 工作台:

SELECT * FROM employeetravelrecords where travel_date between '2015-10-01' and '2015-10-31' or  return_date between '2015-10-01' and '2015-10-31';

我只得到了以下结果:

+----+----------+---------------+----------------+----------+------------------+------------------+----------------+
| id | employee | type          | project        | place    | travel date      | return date      | details        |
+----+----------+---------------+----------------+----------+------------------+------------------+----------------+
| 13 | 38       | International | PVMTC Training | Hongkong | 11/10/2015 13:33 | 28/11/2015 13:33 | PVMTC Training |
| 14 | 48       | International | PVMT           | VIETNAM  | 10/10/2015 9:28  | 1/1/2016 9:28    | PETRO          |
| 17 | 57       | International | PVMT           | Saudi    | 10/10/2015 11:39 | 2/1/2016 11:39   |                |
+----+----------+---------------+----------------+----------+------------------+------------------+----------------+

此查询未检索以下记录:

+---+----+---------------+------+-----+-----------------+-----------------+-----------------+
| 7 | 22 | International | MOHO | XYZ | 29/8/2015 18:00 | 6/11/2015 18:00 | FOR DDS review  |
+---+----+---------------+------+-----+-----------------+-----------------+-----------------+
SELECT * FROM employeetravelrecords
WHERE
        return_date >= '2015-10-01' /* start parameter */
    and travel_date <= '2015-10-31' /* end parameter */

起初,逻辑似乎有点令人费解,我什至从上面的原始评论中对比较进行了一些重新排序。可以这样想:您需要在范围开始返回,并在范围结束之前离开,以便重叠。

有关更长的解释和讨论,您可能会发现此页面很有用:TestIfDateRangesOverlap

SELECT '2015-08-29' < '2015-10-31' AND '2015-11-06' >= '2015-10-01' on_leave;
+----------+
| on_leave |
+----------+
|        1 |
+----------+

您可以使用 between 来获取两个日期之间的数据。这是工作示例。

这是我的表结构:

表用户

 user_id    user_name   created_date            modified_date
 1          lalji nakum 2016-01-28 17:07:06     2016-03-31 00:00:00
 2          admin       2016-01-28 17:25:38     2016-02-29 00:00:00

这是我的mysql查询:

查询

SELECT * FROM `user` WHERE created_date between '2015-12-01' and '2016-12-31' or modified_date between '2015-12-01' and '2016-12-31'

以上查询结果:

结果

user_id     user_name   created_date            modified_date
 1          lalji nakum 2016-01-28 17:07:06     2016-03-31 00:00:00
 2          admin       2016-01-28 17:25:38     2016-02-29 00:00:00

你想找到所有那些在整个持续时间内不可用的人,比如在T1和T2(和T2>T1之间)。您使用的查询将仅提供其开始日期和返回日期都位于给定间隔之间的用户,该间隔不是必需的输出。

因此,

要获得所需的输出,您需要检查所有在 T1 或之前开始旅程且返回日期在 T2 当天或之后的员工(因此无法在完整间隔 [T1, T2] 中使用)。因此,您可以使用的查询是:

SELECT * FROM employeetravelrecords where travel_date <= '2015-10-01' and return_date >= '2015-10-31';

如果您希望员工在给定持续时间内甚至部分不可用,那么我们需要在 T1 之前开始旅行并且返回日期晚于 T1 的员工(从而使他们至少在给定间隔的一部分内不可用):

SELECT * FROM employeetravelrecords where travel_date <= '2015-10-01' and return_date > '2015-10-01';