我需要一些帮助来查询我的日历/日期表
方案: 我有一个"日历"有日期的表格,用户将设置他的可用日期,通常是日复一日。所以我的表看起来像这样:
+------+------------+---------------------+---------------------+
| 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行。
希望有人可以帮助我
答案 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_date
和end_date
(独占)范围内的任何范围,则无法使用。
由于SUM((DATEDIFF(end_date,start_date)+1)) = DATEDIFF(@endDate,@startDate)+1
在这种情况下不相等。 条件
在这种情况下,您需要保持在所需的边界内。这里的边界由end_date
和@endDate
的较小值以及start_date
和@startDate
的较大值划分。
假设您有以下记录(仅一个)
start_date = 2016-09-01
和end_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;