Count overnight hours as one day - sql

I have a dataset where certain operations occur during the overnight hours which I'd like to attribute to the day before.
For example, anything happening between 2/23 8pm and 2/24 6am should be included in 2/23's metrics rather than 2/24. Anything from 6:01 am to 7:59pm should be counted in 2/24's metrics.
I've seen a few posts about decrementing time by 6 hours but that doesn't work in this case.
Is there a way to use an If function to specify that midnight-6am should be counted as date-1 rather than date without affecting the metrics for the 6am - 7:59pm hours?
Thanks in advance! Also, a SQL newbie here so apologies if I have lots of followup questions.

You can use date_add with -6 hours and then optionally cast the timestamp as a date.
create table t (dcol datetime);
insert into t values
('2022-02-25 06:01:00'),
('2022-02-25 06:00:00'),
('2022-02-25 05:59:00');
SELECT CAST(DATE_ADD(dcol, INTERVAL -6 HOUR)AS DATE) FROM t;
| CAST(DATE_ADD(dcol, INTERVAL -6 HOUR)AS DATE) |
| :-------------------------------------------- |
| 2022-02-25 |
| 2022-02-25 |
| 2022-02-24 |
db<>fiddle here

As said in the comments, your requirement is the occurrences in a 6 AM to 6 AM day instead of a 12-12 day. You can achieve this by decreasing the time by 6 hours as shown in #Kendle’s answer. Another way to do it is to use an IF condition as shown below. Here, the date is decremented if the time is before 6 AM on each day and the new date is put in a new column.
Query:
SELECT
IF
(TIME(eventTime) <= "06:00:00",
DATE_ADD(DATE(eventTime), INTERVAL -1 DAY),
DATE(eventTime)) AS newEventTime
FROM
`project.dataset.table`
ORDER BY
eventTime;
Output from sample data:
As seen in the output, timestamps before 6 AM are considered for the previous day while the ones after are considered in the current day.

Related

How to get the day of the week from a time stamp?

I am using Hive .14 to analyze the following input data in timestamp format (# is irrelevant to the explanation):
#
Datetime
1
2022-03-01 00:13:08
2
2022-03-31 23:52:24
3
2022-02-28 23:32:40
and I want to get what day of the week in which each data took place (either by a number representing the day from 0 to 6, or the day itself) in, similar to the next format:
#
Day of the week
1
Tuesday or 2
2
Thursday or 4
3
Monday or 1
I have tried to use the unixtime command to transform the timestamp into an integer
like this:
select cast(from_unixtime(unix_timestamp(datetime,'yyyy-MM-dd'),'yyyyMMdd') as int) as dayint from yellowtaxi;
To later use the from_unixtime(dayint,u) query to get the day of the week in which it happened, however, this results in all the days from all the rows being equal to 20220301 and to all the days being equal to 7 when using from_unixtime(dayint,u).
What am I doing wrong, or is there an easier way to do it?
I have already tried the day_format() and the dayofweek() queries, but none of them seem to be available in my hive version.

Determine date gaps

I have a SQL Server table that has a begin date and end date column that denote the beginning and ending range of a pricing schedule.
As the years go by, many versions of this same schedule will be created, with different beginning and ending dates.
What I would like to do is ensure that the user doesn't add, or, in some cases edit, a beginning or ending date in such a way that days would be excluded in the overall time frame.
So if the data looked like this:
Start | End
-----------+--------------
01/01/2015 | 06/30/2015
07/01/2015 | 09/30/2016
10/01/2016 | 12/31/2020
So, lets assume I attempted to revised the last row Start to 10/15/2016. That would create a gap of days between 10/01/2016 and 10/14/2016, but I have no idea who to write a script to do this for me. Ultimately, I would like a list of all missing dates, but even a count of days missing would be great.
Is this possible or am I approaching the issue incorrectly? Any ideas?
Using SQL Server 2012, if it matters.
I am guessing you don't want overlaps either. So, just use lag() and check that it is the date before:
select t.*
from (select t.*,
lag(end_date) over (order by start_date) as prev_end_date
from t
) t
where start_date <> dateadd(day, 1, prev_end_date)

How can I calculate the number of minutes per day between a daterange

First off I apologize I do not even know where to start and haven't been able to find anything specific to this particular question.
I have a table with datetimes (start and end) and i need to find a way to get minutes/hours between those days. It could either be a sum of the time on weekdays or a some kind of pivot on each day and grouping by the ID number. I had thought to assign a value to the number of days however the times are random and do not start/end at midnight so I am at a loss as how to approach this.
Here are some examples of the date/time format if that helps.
startdate 2018-12-14 10:53:01
enddate 2018-12-27 11:50:00
Any helps or hints would be greatly appreciated!
Edit
forgot to include I am working in SQL Server (SSMS)
Editing For Additional Clarification
Here is a sample date range with an ID number, I wanted to keep it simple.
|ID number| start time |end time
|1 |12/14/2018 10:53|12/17/2018 12:00
here is what I'm trying to achieve (the separation of each date range/ID #)
ID number| start time |end time |mins|
1 | 12/14/2018 10:53|12/14/2018 23:59|786 |
1 | 12/15/2018 0:00 |12/15/2018 23:59|1439|
1 | 12/16/2018 0:00 |12/16/2018 23:59|1439|
1 | 12/17/2018 0:00 |12/17/2018 12:00|960 |
The MINUTE parameter of the DATEDIFF function can be used to determine the difference in minutes between two datetime columns. As below, the second parameter is the start date and the third parameter is the end date, with the result being the amount of time in the specified interval (days, minutes, etc.) from the start to the end date. If you need to find the number of hours between these two columns the HOUR parameter can be used for this. Grouping can be performed as well, as in the second example.
DATEDIFF:
SELECT DATEDIFF(MINUTE, StartDateColumn, EndDateColumn)
DATEDIFF with Grouping and Aggregation:
SELECT ColumnA, SUM(DATEDIFF(MINUTE, StartDateColumn, EndDateColumn)) as DifferenceInMinutes
FROM YourSchema.YourTable
GROUP BY ColumnA

Average ticket response time by week with SQL query

In my Spiceworks database there is a table, tickets, with two columns I am concerned with, first_response_secs and created_at.
I have been tasked with finding the average response time of tickets for every week.
So if I run the following query:
select AVG(first_response_secs) from (
select first_response_secs,created_at
from tickets
where created_at BETWEEN '2017-03-19' and '2017-03-25'
)
I will get back the average first response seconds for that week. But that's as far as my limited SQL gets me. I need 6 months worth of data and I don't want to manually edit the date range and rerun the query 24 times.
I would like to write a query that will return output similar to the following:
WEEK AVERAGE RESPONSE TIME(secs)
-----------------------------------------------------------
2017-02-26 - 2017-03-04 21447
2017-03-05 - 2017-03-11 20564
2017-03-12 - 2017-03-18 25883
2017-03-19 - 2017-03-25 12244
Or something like that, back 6 months.
Weeks are tricky. How about:
select min(created_at) as weekstart, first_response_secs, created_at
from tickets
group by floor(julianday('2017-03-25) - julianday(created_at)) % 7 = 0
order by weekstart
One dirty way is to use case to define week boundaries:
select week, avg(first_response_secs)
from (
select case
when created_at between '2017-02-26' and '2017-03-04' then '2017-02-26 - 2017-03-04'
when created_at between '2017-03-05' and '2017-03-11' then '2017-03-05 - 2017-03-11'
when created_at between '2017-03-12' and '2017-03-18' then '2017-03-12 - 2017-03-18'
when created_at between '2017-03-19' and '2017-03-25' then '2017-03-19 - 2017-03-25'
end as week,
first_response_secs
from tickets
) t
group by week;
Demo
Note that this method is a general purpose one and can be modified to change the boundaries as you wish.

MySQL: How to calculate weeks out from a specific date?

I need to calculate the weeks out from a date in my MySQL select statement. There is a date column in one of the tables, and I need to calculate how many weeks away the date is.
SELECT EventDate, (calculation) AS WeeksOut FROM Events;
Example:
6 days away, weeks out = 0
7 days away, weeks out = 1
13 days away, weeks out = 1
14 days away, weeks out = 2
Use the DATEDIFF function:
ROUND(DATEDIFF(end_date, start_date)/7, 0) AS weeksout
The problem with WEEKS is that it won't return correct results for dates that cross over January 1st.
The 0 is the number of decimal places to use in the ROUND function.
In order to get past the whole "New Year" issue and you still want to use WEEK(), I found the following method quite effective.
SELECT
YEAR(end_date)*52+WEEK(end_date)
- YEAR(start_date)*52 - WEEK(start_date) as weeks_out
FROM
events;
The difference with this method (as opposed to the DATEDIFF method) is that it is aligned with the week. So today (which is Monday) and last Friday would return 1 using this method, but would return 0 with the DATEDIFF method
Here's a simple way to do it:
SELECT EventDate, (week(EventDate) - week(curdate())) AS WeeksOut FROM Events;
Example:
mysql> select week('2010-11-18') - week ('2010-10-18');
+------------------------------------------+
| week('2010-11-18') - week ('2010-10-18') |
+------------------------------------------+
| 4 |
+------------------------------------------+
1 row in set (0.00 sec)
Another option is calculate the interval in days and divide by 7:
SELECT EventDate, datediff(EventDate,curdate())/7 AS WeeksOut FROM Events;
Example:
mysql> select datediff('2010-11-18' , '2010-10-18') / 7;
+-------------------------------------------+
| datediff('2010-11-18' , '2010-10-18') / 7 |
+-------------------------------------------+
| 4.4286 |
+-------------------------------------------+
1 row in set (0.00 sec)
In newer versions of MYSQL if you use the timestamp as column type, you can use TIMESTAMPDIFF:
SELECT TIMESTAMPDIFF(WEEK, '2020-06-09 08:59:36', '2020-09-09 08:58:25');
|-----------------------------------------------------------------------|
| 13 |
So in your example it would be:
SELECT TIMESTAMPDIFF(WEEK, NOW(), EventDate) AS WeeksOut FROM Events;
Try TIMESTAMPDIFF
TIMESTAMPDIFF(WEEK, curdate(), EventDate) AS WEEKS_DIFFERENCE