我有一个名为'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查询。
你不知道该怎么做吗?有什么建议吗?
谢谢!
答案 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)
您需要在范围内开始和结束的事件。但这并非全部:您还需要在范围内开始的事件以及在范围内结束的事件。但是你仍然不在那里因为你也想要在范围之前开始并在范围之后结束的事件。
简化为:
因为第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'
输出:
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)