18

I have a MySQL table named 'events' that contains event data. The important columns are 'start' and 'end' which contain string (YYYY-MM-DD) to represent when the events starts and ends.

I want to get the records for all the active events in a time period.

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 |
------------------------------

Request/search:

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

I tried many queries still I fail to get the exact SQL query.

Don't you know how to do that? Any suggestions?

Thanks!

Salman A
  • 262,204
  • 82
  • 430
  • 521
Guicara
  • 1,668
  • 2
  • 20
  • 34
  • Do you want a single query? – Fabio Jun 09 '13 at 20:57
  • I search a more elegant query. I'm pretty sure this one is not very good. I have tried with 'BETWEEN start AND end' without success. The problem is when I have date withe start == end. – Guicara Jun 09 '13 at 21:00
  • @Guicara added this condition of start and end in my answer – echo_Me Jun 09 '13 at 21:12
  • Your answers have helped me, thank you. By creating this topic, I thought my answer (my queries) were bad in some cases, but infact it was not! This is the problem when we are stuck on a problem for long hours: answer can jumped out at you, without seeing it. – Guicara Jun 09 '13 at 21:49
  • 1
    In your first example, #2 is an ongoing event during your scope. Wouldn't an ongoing event be the same thing as an active event? And if for another example: All events [active] between 2013-06-22 and 2013-06-23 wouldn't #2 and #3 both be active events? – amaster Dec 08 '17 at 05:02

11 Answers11

26

If I understood correctly you are trying to use a single query, i think you can just merge your date search toghter in WHERE clauses

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

or even more simply you can just use both column to set search time filter

SELECT id 
FROM events 
WHERE start >= '2013-07-22' AND end <= '2013-06-13'
Fabio
  • 23,183
  • 12
  • 55
  • 64
  • I have had ready from a while, waiting for op answer at my comment – Fabio Jun 09 '13 at 21:03
  • You have both answered at the same time :) Your answers have helped me, thank you. By creating this topic, I thought my answer (my queries) were bad in some cases, but infact it was not! This is the problem when we are stuck on a problem for long hours: answer can jumped out at you, without seeing it. – Guicara Jun 09 '13 at 21:48
  • @Guicara I'm glad i helped you out, please consider accepting one answer, your best one, to close your issue – Fabio Jun 09 '13 at 21:50
  • @Guicara in fact he posted after me and i told him that he copy paste my answer – echo_Me Jun 09 '13 at 21:54
  • 1
    @echo_Samir I give you a '+1' and I select Fabio answer. I would have validated your two answers, but Stackoverflow does not allow it. – Guicara Jun 09 '13 at 21:57
  • 1
    @echo_Samir I think OP is free to decide which answer is better for him, he's not supposed to accept first answer but what he thinks is the best – Fabio Jun 09 '13 at 21:59
  • 8
    this answer does not include ongoing events. IMO Ongoing events that may either start before or end after the date range should be part of 'all the active events in a time period' – amaster Dec 08 '17 at 04:41
  • That is not correct. Use: `SELECT id FROM events WHERE ( ( start >= '2013-07-22' OR end >= '2013-07-22') AND ( end <= '2013-06-13' OR start <= '2013-06-13') ); ` – TheAlphaGhost Mar 18 '21 at 13:07
  • That is incorrect e.g. does not work when the start-end date _contains_ the event. Technically, such events should be considered _active in that time period_. – Salman A Nov 18 '21 at 11:30
22

You need the events that start and end within the scope. But that's not all: you also want the events that start within the scope and the events that end within the scope. But then you're still not there because you also want the events that start before the scope and end after the scope.

Simplified:

  1. events with a start date in the scope
  2. events with an end date in the scope
  3. events with the scope startdate between the startdate and enddate

Because point 2 results in records that also meet the query in point 3 we will only need points 1 and 3

So the SQL becomes:

SELECT * FROM events 
WHERE start BETWEEN '2014-09-01' AND '2014-10-13' 
OR '2014-09-01' BETWEEN start AND end
Peter de Groot
  • 829
  • 7
  • 12
15

Here lot of good answer but i think this will help someone

select id  from campaign where ( NOW() BETWEEN start_date AND end_date) 
Saurabh Chandra Patel
  • 12,712
  • 6
  • 88
  • 78
10
SELECT id
FROM events
WHERE start <= '2013-07-22'
AND end >= '2013-06-13';

Or use MIN() and MAX() if you don't know the precedence.

Olivier Coilland
  • 3,088
  • 16
  • 20
  • Thank for you answer! It works, but I think that you have reversed the start / end date. The correct query sould be: SELECT id FROM events WHERE start <= '2013-06-13' AND end >= '2013-07-22' – Guicara Jun 09 '13 at 21:51
  • 2
    @Guicara, this is actually one of the ONLY CORRECT answers listed here. Let me explain. Let's say an event started on 2013-01-01, and ended on 2013-12-31. Should this event be included in the query? I believe yes it should because it is an ongoing active event during the range you have selected. Unless you mean 'all the active events in a time period' as ONLY events that start AND end WITHIN the date range. I recently ran into this 'bug' in my script because I was using one of the other answers. I believe that you want events that start before the end date and end after the start date. – amaster Dec 08 '17 at 04:27
  • @amaster exactly... you are correct. Thanks for sharing very thoughtful insight about this query. I really appreciate your effort in providing useful comment – Sandeep Garg Mar 25 '19 at 07:50
5
SELECT *
FROM events 
WHERE endDate >= @startDate AND startDate <= @endDate

For explanation refer to this diagram:

enter image description here

  • Suppose sample data is [startDate: 2020-10-01, endDate: 2020-20-01]
  • The user provides @startDate and @endDate to search
  • For overlap there are 4 scenarios and 1 variation (red/maroon lines)
  • For no overlap there are just 2 scenarios (green lines)

So, in order to get overlapping dates by providing start and end date, endDate must be greater than @startDate and startDate must be less than @endDate.

Salman A
  • 262,204
  • 82
  • 430
  • 521
4
SELECT * 
FROM events 
WHERE start <= '2013-07-22' OR end >= '2013-06-13'
Philip Sheard
  • 5,789
  • 5
  • 27
  • 42
  • I believe there is a typo here or this is a wrong answer. it should be WHERE start <= ToDate OR end >= FromDate – amaster Dec 08 '17 at 04:30
  • [at signs removed from my comment due to restraints of StackOverflow tagging multiple users] – amaster Dec 08 '17 at 04:31
  • Thanks. I have restored my original SQL. Someone had edited it, for no particular reason, and ruined the simplicity of it. I believe that mine is the simplest solution. – Philip Sheard Dec 08 '17 at 08:43
1

EDIT: I've squeezed the filter a lot. I couldn't wrap my head around it before how to make sure something really fit within the time period. It's this: Start date BEFORE the END of the time period, and End date AFTER the BEGINNING of the time period

With the help of someone in my office I think we've figured out how to include everyone in the filter. There are 5 scenarios where a student would be deemed active during the time period in question:

1) Student started and ended during the time period.

2) Student started before and ended during the time period.

3) Student started before and ended after the time period.

4) Student started during the time period and ended after the time period.

5) Student started during the time period and is still active (Doesn't have an end date yet)

Given these criteria, we can actually condense the statements into a few groups because a student can only end between the period dates, after the period date, or they don't have an end date:

1) Student ends during the time period AND [Student starts before OR during]

2) Student ends after the time period AND [Student starts before OR during]

3) Student hasn't finished yet AND [Student starts before OR during]

   (
        (
         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'
   )

I think this finally covers all the bases and includes all scenarios where a student, or event, or anything is active during a time period when you only have start date and end date. Please, do not hesitate to tell me that I am missing something. I want this to be perfect so others can use this, as I don't believe the other answers have gotten everything right yet.

0

try this

    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

output :

 ID
 1
 3
 4
echo_Me
  • 37,078
  • 5
  • 58
  • 78
  • Thank, but "AND start != end" is unnecessary / wrong (because I can have a event that start and end the same day). – Guicara Jun 09 '13 at 21:51
  • ok its just because you mentioned in your question that you have problem with start and end have same day . anyway i edited my answer – echo_Me Jun 09 '13 at 21:53
  • 1
    This will not retrieve events that start before and end after; start before and end during; or start during and end after. An ongoing event IMO is an 'active events in a time period' – amaster Dec 08 '17 at 04:36
0

If you would like to use INTERSECT option, the SQL is as follows

(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') 
bkm
  • 109
  • 1
  • 8
  • What about events that start before the scope and end after the scope? Wouldn't they be considered active events? Ongoing=Active? Your answer only retrieves events that start AND end within the scope. – amaster Dec 08 '17 at 04:56
  • how do I select all records that have an event datetime within 1 hour before, for example mysql select all that time_diff less than 1 hour from datetime? its for a reminder email i want to make on a cronjob can you help with this sql query? – Jay Mee Nov 09 '22 at 21:59
0

In PHP and 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."'";
oscar castellon
  • 3,048
  • 30
  • 19
0

If anyone is searching for a situation when the current date is residing between two periods (start/end date) in Microsoft SQL, please find below

select id from campaign where (getdate() BETWEEN start_date AND end_date) 
Vinu V
  • 1
  • 2
  • what about 1 hour before an event start time, for a reminder how can I do this?, (I cant start a question it wont let me)? – Jay Mee Nov 09 '22 at 21:54