根据日期范围之间的日期列获取可用用户

时间:2016-02-18 11:05:19

标签: php mysql

我有两张桌子:

1) Users
2) Calendars

每个用户都有自己的日历。他们可以选择一系列日期并将其标记为:

=> Available (1)
=> UnAvailable (2)

现在,最初日历表将为空,表示所有用户每天都可用。现在我想要在给定的日期范围内可用的所有用户。例如:我的数据库现在看起来像这样:

1)用户

-----------------
id  name
-----------------
1    abc
2    lmn
3    xyz

2)日历

------------------------------------------------------------------------
id      user_id        start_date            end_date           type
------------------------------------------------------------------------
1          2           2016-02-20             2016-02-25          2
2          2           2016-02-20             2016-02-25          1
3          2           2016-02-22             2016-02-24          2

现在如果我在2016-02-20到2016-02-25之间搜索用户,我应该得到用户1和3,因为2在2016-02-22到2016-02-24之间是不可能的。

此外,如果我在2016-02-20至2016-02-22或2016-02-24至2016-02-26之间搜索,那么我也应该获得用户1和3。

直到现在我已经尝试过这段代码,但这似乎无法正常工作。

$query = "
    SELECT users.id FROM users 
    WHERE id NOT IN 
    ( 
        SELECT user_id FROM calendars 
        WHERE ( '2016-02-20' >= `start_date` AND '2016-02-25' <= `end_date`) 
        OR ( '2016-02-20' <= `start_date` AND '2016-02-25' >= `end_date`) 
        OR ( `start_date` BETWEEN '2016-02-20' AND '2016-02-25') 
        OR ( `end_date` BETWEEN '2016-02-20' AND '2016-02-25')  
        AND type = 2 
    )
";

    $users = \DB::select(  \DB::raw($query) );
    $availableusers = [];
    foreach ($users as $user) {
        $availableusers[] = $user->id;
    }
    return $availableusers;

请帮帮我。

##更新2

其他情况:

1) Users
-----------------
id  name
-----------------
1    abc
2    lmn
3    xyz

2) Calendars
------------------------------------------------------------------------
id      user_id        start_date            end_date           type
------------------------------------------------------------------------
1          2           2016-02-21             2016-02-25          2
2          2           2016-02-21             2016-02-25          1
3          3           2016-02-23             2016-02-24          2

在这里搜索'2016-02-21'和'2016-02-23'我应该在availbale lisy中获得用户2

1 个答案:

答案 0 :(得分:1)

您可以使用NOT EXISTS():

SELECT * FROM Users s
WHERE NOT EXISTS(select 1 from Calender t
                 where t.user_id = s.id and t.type = 2
                       and ((t.start_date between YourStartRange and YourEndRange)
                            OR(t.end_date between YourStartRange and YourEndRange)
                            OR(YourStartRange between t.start_date and t.end_date)))

这取得了所有可能性:

  • 给定范围在范围之前开始并在它们之间结束
  • 给定范围从它们之间开始并在它们之后结束
  • 给定范围介于两者之间