SQL / Mysql查询数据库中的可用日期

时间:2016-09-17 11:08:12

标签: mysql sql date web calendar

我需要一些帮助来查询我的日历/日期表

方案: 我有一个"日历"有日期的表格,用户将设置他的可用日期,通常是日复一日。所以我的表看起来像这样:

+------+------------+---------------------+---------------------+ 
| ID   | user_id    | start_date          | end_date            | 
+------+------------+---------------------+---------------------+ 
|    1 |          1 | 2016-09-01 08:00:00 | 2016-09-01 16:00:00 | 
|    2 |          1 | 2016-09-03 08:00:00 | 2016-09-03 16:00:00 | 
|    3 |          1 | 2016-09-04 08:00:00 | 2016-09-04 16:00:00 | 
|    3 |          1 | 2016-09-05 08:00:00 | 2016-09-05 16:00:00 | 
+------+------------+---------------------+---------------------+ 

这意味着用户1在第1,第3,第4和第5位可用。

假设我想查询表并查找用户是否可以从日期2016-09-01 08:00:00到2016-09-05 16:00:00,此查询必须返回零行,因为用户9月2日不可用。但是如果从2016-09-03 08:00:00到2016-09-05 16:00:00查询,那么它将返回这3行。

希望有人可以帮助我

2 个答案:

答案 0 :(得分:2)

这可能是一种方式(对于单个用户)。

注意@endDate@startDate是要搜索的提供日期字段。

SELECT 
*
FROM your_table 
WHERE EXISTS (
    SELECT 
    user_id
    FROM your_table 
    WHERE start_date >= @startDate 
    AND start_date <= @endDate
    AND user_id = 1
    GROUP BY user_id 
    HAVING SUM((DATEDIFF(end_date,start_date)+1)) = DATEDIFF(@endDate,@startDate)+1
)
AND start_date >= @startDate 
AND start_date <= @endDate
AND user_id = 1

注意:

如果提供的日期范围属于start_dateend_date(独占)范围内的任何范围,则无法使用。

由于SUM((DATEDIFF(end_date,start_date)+1)) = DATEDIFF(@endDate,@startDate)+1在这种情况下不相等。 条件

在这种情况下,您需要保持在所需的边界内。这里的边界由end_date@endDate的较小值以及start_date@startDate的较大值划分。

假设您有以下记录(仅一个)

start_date = 2016-09-01end_date=2016-09-05

@startDate=2016-09-02@endDate=2016-09-04

现在检查上述条件对于这组数据是否会失败。

在这种情况下,您需要采用以下查询:

SELECT 
*
FROM your_table 
WHERE EXISTS (
    SELECT 
    user_id
    FROM your_table 
    WHERE end_date >= @startDate 
    AND start_date <= @endDate
    AND user_id = 1
    GROUP BY user_id 
    HAVING SUM((DATEDIFF(LEAST(end_date,@endDate),GREATEST(start_date,@startDate))+1)) = DATEDIFF(@endDate,@startDate)+1
)
AND end_date >= @startDate 
AND start_date <= @endDate
AND user_id = 1

答案 1 :(得分:0)

假设表格中的句点不重叠,您可以计算天数。那段时间的日子是:

select sum(datediff(least($period_end, end_date),
                    greatest($period_start, start_date)
                   ) + 1
          )
from t
where $period_start <= end_date and
      $period_end >= start_date;

然后,您可以通过与天数比较得到一个标志:

select (case when sum(datediff(least($period_end, end_date),
                               greatest($period_start, start_date)
                              ) + 1
                     ) =
                  datediff($period_end, $period_start) + 1
             then 1 else 0
        end) as IsAvailableForAllDays
from t
where $period_start <= end_date and
      $period_end >= start_date;