MySQL查询选择开始/结束日期之间的事件

时间:2013-06-09 20:53:18

标签: mysql sql date date-range

我有一个名为'events'的MySQL表,其中包含事件数据。重要的列是'start'和'end',它们包含字符串(YYYY-MM-DD)以表示事件的开始和结束时间。

我想获取一段时间内所有活动事件的记录。

活动:

------------------------------
ID | START      | END        |
------------------------------
1  | 2013-06-14 | 2013-06-14 |
2  | 2013-06-15 | 2013-08-21 |
3  | 2013-06-22 | 2013-06-25 |
4  | 2013-07-01 | 2013-07-10 |
5  | 2013-07-30 | 2013-07-31 |
------------------------------

请求/检索:

Example: All events between 2013-06-13 and 2013-07-22 : #1, #3, #4

SELECT id FROM events WHERE start BETWEEN '2013-06-13' AND '2013-07-22' : #1, #2, #3, #4
SELECT id FROM events WHERE end   BETWEEN '2013-06-13' AND '2013-07-22' : #1, #3, #4
====> intersect : #1, #3, #4
Example: All events between 2013-06-14 and 2013-06-14 : 

SELECT id FROM events WHERE start BETWEEN '2013-06-14' AND '2013-06-14' : #1
SELECT id FROM events WHERE end   BETWEEN '2013-06-14' AND '2013-06-14' : #1
====> intersect : #1

我尝试了很多查询仍然无法获得确切的SQL查询。

你不知道该怎么做吗?有什么建议吗?

谢谢!

11 个答案:

答案 0 :(得分:17)

如果我理解正确您尝试使用单个查询,我认为您可以将日期搜索合并到WHERE子句中

SELECT id 
FROM events 
WHERE start BETWEEN '2013-06-13' AND '2013-07-22' 
AND end BETWEEN '2013-06-13' AND '2013-07-22'

或者更简单地说,您可以使用两列来设置搜索时间过滤器

SELECT id 
FROM events 
WHERE start >= '2013-07-22' AND end <= '2013-06-13'

答案 1 :(得分:12)

您需要在范围内开始和结束的事件。但这并非全部:您还需要在范围内开始的事件以及在范围内结束的事件。但是你仍然不在那里因为你也想要在范围之前开始并在范围之后结束的事件。

简化为:

  1. 在范围内具有开始日期的事件
  2. 结束日期在范围内的事件
  3. startdate和enddate之间范围为startdate的事件
  4. 因为第2点导致记录也符合第3点的查询,所以我们只需要第1点和第3点

    所以SQL变成了:

    SELECT * FROM events 
    WHERE start BETWEEN '2014-09-01' AND '2014-10-13' 
    OR '2014-09-01' BETWEEN start AND end
    

答案 2 :(得分:7)

这里有很多好的答案,但我认为这会有所帮助

select id  from campaign where ( NOW() BETWEEN start_date AND end_date) 

答案 3 :(得分:5)

SELECT id
FROM events
WHERE start <= '2013-07-22'
AND end >= '2013-06-13';

如果您不知道优先级,请使用MIN()MAX()

答案 4 :(得分:2)

我假设某个时间段内活动事件表示事件中至少有一天属于该时间段内。这是一个简单的“查找重叠日期”问题,并且有一个通用解决方案:

-- [@d1, @d2] is the date range to check against
SELECT * FROM events WHERE @d2 >= start AND end >= @d1

一些测试:

-- list of events
SELECT * FROM events;
+------+------------+------------+
| id   | start      | end        |
+------+------------+------------+
|    1 | 2013-06-14 | 2013-06-14 |
|    2 | 2013-06-15 | 2013-08-21 |
|    3 | 2013-06-22 | 2013-06-25 |
|    4 | 2013-07-01 | 2013-07-10 |
|    5 | 2013-07-30 | 2013-07-31 |
+------+------------+------------+

-- events between [2013-06-01, 2013-06-15]
SELECT * FROM events WHERE '2013-06-15' >= start AND end >= '2013-06-01';
+------+------------+------------+
| id   | start      | end        |
+------+------------+------------+
|    1 | 2013-06-14 | 2013-06-14 |
|    2 | 2013-06-15 | 2013-08-21 |
+------+------------+------------+

-- events between [2013-06-16, 2013-06-30]
SELECT * FROM events WHERE '2013-06-30' >= start AND end >= '2013-06-16';
+------+------------+------------+
| id   | start      | end        |
+------+------------+------------+
|    2 | 2013-06-15 | 2013-08-21 |
|    3 | 2013-06-22 | 2013-06-25 |
+------+------------+------------+

-- events between [2013-07-01, 2013-07-01]
SELECT * FROM events WHERE '2013-07-01' >= start AND end >= '2013-07-01';
+------+------------+------------+
| id   | start      | end        |
+------+------------+------------+
|    2 | 2013-06-15 | 2013-08-21 |
|    4 | 2013-07-01 | 2013-07-10 |
+------+------------+------------+

-- events between [2013-07-11, 2013-07-29]
SELECT * FROM events WHERE '2013-07-29' >= start AND end >= '2013-07-11';
+------+------------+------------+
| id   | start      | end        |
+------+------------+------------+
|    2 | 2013-06-15 | 2013-08-21 |
+------+------------+------------+

答案 5 :(得分:1)

SELECT * 
FROM events 
WHERE start <= '2013-07-22' OR end >= '2013-06-13'

答案 6 :(得分:0)

试试这个

    SELECT id FROM events WHERE start BETWEEN '2013-06-13' AND '2013-07-22' 
                          AND   end   BETWEEN '2013-06-13' AND '2013-07-22'

DEMO HERE

输出:

 ID
 1
 3
 4

答案 7 :(得分:0)

如果您想使用INTERSECT选项,SQL如下

(SELECT id FROM events WHERE start BETWEEN '2013-06-13' AND '2013-07-22') 
INTERSECT
(SELECT id FROM events WHERE end BETWEEN '2013-06-13' AND '2013-07-22') 

答案 8 :(得分:0)

编辑:我挤了很多过滤器。在确定某个时间段内确实合适之前,我无法解决这个问题。就是这样:时间段结束之前的开始日期,时间段开始之后的结束日期

在我办公室里的某个人的帮助下,我认为我们已经弄清楚了如何将所有人包括在过滤器中。 在有问题的时间段内,有5种情况将学生视为活跃学生:

1)学生在该时间段内开始和结束。

2)学生在该时段之前开始并结束。

3)学生在该时间段之前开始并在该时间段之后结束。

4)学生在该时间段内开始,并在该时间段后结束。

5)学生在该时间段内开始学习,但仍处于活动状态(还没有结束日期)

基于这些条件,我们实际上可以将语句压缩为几组,因为学生只能在期间日期之后,期间日期之后结束,或者他们没有结束日期:

1)学生在这段时间内结束,并且[学生在OR之前开始]

2)学生在该时间段后结束,并且[学生在OR之前开始]

3)学生尚未完成,并且[学生在OR之前开始学习]

   (
        (
         student_programs.END_DATE  >=  '07/01/2017 00:0:0'
         OR
         student_programs.END_DATE  Is Null  
        )
        AND
        student_programs.START_DATE  <=  '06/30/2018 23:59:59'
   )

我认为,这最终涵盖了所有基础,并包括了在只有开始日期和结束日期的时间段内,学生,事件或任何事物都处于活动状态的所有场景。拜托,不要犹豫告诉我,我错过了一些东西。我希望它是完美的,以便其他人可以使用它,因为我不认为其他答案还可以解决所有问题。

答案 9 :(得分:0)

在PHP和phpMyAdmin中

$tb = tableDataName; //Table name
$now = date('Y-m-d'); //Current date

//start and end is the fields of tabla with date format value (yyyy-m-d)

$query = "SELECT * FROM $tb WHERE start <= '".$now."' AND end >= '".$now."'";

答案 10 :(得分:0)

select * from tbl where (endDate>=@starDate and startDate<=@endDate)

附上图表进行说明enter image description here

在数据库StartDate = 10/01/2020和endDate = 20/01/2020中存储简单数据。 用户可以提供@startDate(d1)和@endDate(d2)进行搜索。

在此情况下,可能会发生4条红线(匹配数据),2条绿线(没有匹配数据)描述的6种情况。

因此,根据图像的结论,可以通过提供d1,d2从DB获取数据。 ED必须大于d1(@startDate),SD必须小于d2(@endDate)。