Reputation: 83
I am trying to query a table that is setup with id, startDateTime, endDateTime. Let's say row 1 looks like this:
id startDateTime endDateTime
100 2/9/2012 20:55 3/21/2012 10:43
I need to query the above such that I get a distinct count of all the days in the above range. My expected result would be in the above 42 as there are 42 unique calendar days from 2/9 through 3/21. Datediff because it looks at the time piece gives me 41 days. I have tried various iterations of datediff and timediff trying to get this to work but can't find anything that works in all scenarios. Any suggestions as to how this can be done in SQL?
I started with a query as shown below:
SELECT ConditionStatus.ID,
SUM((DATEDIFF(ConditionStatus.endDate,ConditionStatus.startDate))) AS Duration
WHERE ID = 100
My query returns a Duration of 41 which is technically accurate but I need to condition such that every date in the range of dates gets a count of 1
I am trying to mimic some logic we use on our datawarehouse where we persist a count of 1 for each date for which there was activity.
Thanks, Bob
Upvotes: 0
Views: 599
Reputation: 967
See this answer - How do I select the number of distinct days in a date range?
Take a look before you use @Ike's answer. If you add +1, you will get one too many in instances where the time value is 00:00:00.
select datediff(days, '2/9/2012 20:55', '3/21/2012 10:43')
returns 41
select datediff(days, '2/9/2012 20:55', '3/21/2012 10:43') + 1
returns 42
This is where that breaks -
select datediff(days, '2/9/2012 20:55', '3/21/2012 00:00:00') + 1
returns 42
That's the wrong answer. It should not include the last day.
Here's the workaround -
datediff(days, '2/9/2012 20:55', dateadd(seconds, -1, '3/21/2012 00:00:00') + 1
Upvotes: 0
Reputation: 65537
The basic answer is that you can use DATEDIFF()
and add 1 because you want to include the current day.
For example:
mysql> select datediff(current_date(),current_date()) + 1;
+---------------------------------------------+
| datediff(current_date(),current_date()) + 1 |
+---------------------------------------------+
| 1 |
+---------------------------------------------+
1 row in set (0.00 sec)
Expanding on your original example, you can convert the strings to datetimes, then discard the time component, then calculate the inclusive date count with a query like this:
mysql> SELECT ABS(DATEDIFF(DATE(STR_TO_DATE('2/9/2012 20:55','%m/%d/%Y %H:%i')),
-> DATE(STR_TO_DATE('3/21/2012 10:43','%m/%d/%Y %H:%i')))) + 1 as days_in_range;
+---------------+
| days_in_range |
+---------------+
| 42 |
+---------------+
1 row in set (0.00 sec)
mysql> SELECT ABS(DATEDIFF(DATE(STR_TO_DATE('3/21/2012 10:43','%m/%d/%Y %H:%i')),
-> DATE(STR_TO_DATE('2/9/2012 20:55','%m/%d/%Y %H:%i')))) + 1 as days_in_range;
+---------------+
| days_in_range |
+---------------+
| 42 |
+---------------+
1 row in set (0.00 sec)
Upvotes: 3