Split time intervals on the hour - sql

I have a data set:
tbldataid TS EndTS
> HX32.3401 10/2/2017 11:49:34 PM 10/3/2017 12:01:57 AM
> HX32.3403 10/3/2017 12:02:48 AM 10/3/2017 12:08:34 AM
> HX32.3425 10/3/2017 2:50:57 AM 10/3/2017 2:50:58 AM
> HX32.3428 10/3/2017 4:06:15 AM 10/3/2017 6:09:19 AM
I would like to to essentially 'split' these intervals on the hour, such as:
tbldataid TS EndTS
HX32.3401 10/2/2017 11:49:34 PM 10/2/2017 11:59:99 PM
HX32.3401 10/2/2017 12:00:00 PM 10/3/2017 12:01:57 AM
HX32.3403 10/3/2017 12:02:48 AM 10/3/2017 12:08:34 AM
HX32.3425 10/3/2017 2:50:57 AM 10/3/2017 2:50:58 AM
HX32.3428 10/3/2017 4:06:15 AM 10/3/2017 4:59:99 AM
HX32.3428 10/3/2017 5:00:00 AM 10/3/2017 5:59:99 AM
HX32.3428 10/3/2017 6:00:00 AM 10/3/2017 6:09:19 AM
Here is my code so far (credit for the idea goes to #Dumitrescu Bogdan, Split call data to 15 minute intervals):
SELECT [tbldataid],[TS],
IIF([EndTS]<=dateadd("n",60*((datediff("n",0,[TS]/60))+.99),0),
[EndTS],
dateadd("n", 60*(datediff("n",0,[TS]/60)+.99),0))
as [End]
FROM tbldata
UNION ALL
SELECT t2.[tbldataid], t2.[TS],
IIF(t1.[EndTS]<=dateadd("n",60*((datediff("n",0, t2.[EndTS])/60)+1),0),
t1.[EndTS],
dateadd("n",60*((datediff("n",0,t2.[EndTS])/60)+1),0))
as [End]
FROM
tbldata t1
LEFT JOIN tbldata t2
ON t1.[tbldataid]=t2.[tbldataid]
Where t2.[EndTS]<IIF(t1.[EndTS]<=dateadd("n",60*((datediff("n",0,t2.[EndTS])/60)+1),0),
t1.[EndTS],
dateadd("n",60*((datediff("n",0,t2.[EndTS])/60)+1),0));
The second half (after 'union all') doesn't produce any result, the first half produces the following:
tbldataid TS End
HX32.3401 10/2/2017 11:49:34 PM 10/2/2017 11:59:00 PM
HX32.3403 10/3/2017 12:02:48 AM 10/3/2017 12:08:34 AM
HX32.3425 10/3/2017 2:50:57 AM 10/3/2017 2:50:58 AM
HX32.3428 10/3/2017 4:06:15 AM 10/3/2017 4:59:00 AM
Thanks, I'm a beginner. I understand the first part; admittedly I don't understand the second half
I'm open to other solutions.
I'm using MS-Access 2010

This can be done with a Cartesian query:
SELECT DISTINCT
tblData.tblDataId,
IIf([TimeStart] > DateAdd("h",[Factor],CDate(Fix([Timestart]*24)/24)),
[TimeStart],
DateAdd("h",[Factor],CDate(Fix([Timestart]*24)/24))) AS TSStart,
IIf([TimeEnd] < DateAdd("s",3599,DateAdd("h",[Factor],CDate(Fix([Timestart]*24)/24))),
[TimeEnd],
DateAdd("s",3599,DateAdd("h",[Factor],CDate(Fix([Timestart]*24)/24)))) AS TSEnd
FROM
qdxFactor,
tblData
WHERE
qdxFactor.Factor Between 0 And DateDiff("h",[TimeStart],[TimeEnd]);
using this other saved Cartesian query (qdxFactor):
SELECT DISTINCT
[Tens]+[Ones] AS Factor,
10*Abs([Deca].[id] Mod 10) AS Tens,
Abs([Uno].[id] Mod 10) AS Ones
FROM
MSysObjects AS Uno,
MSysObjects AS Deca;
Result:
tblDataId TSStart TSEnd
3401 2017-10-02 23:49:34 2017-10-02 23:59:59
3401 2017-10-03 00:00:00 2017-10-03 00:01:57
3403 2017-10-03 00:02:48 2017-10-03 00:08:34
3425 2017-10-03 02:50:57 2017-10-03 02:50:58
3428 2017-10-03 04:06:15 2017-10-03 04:59:59
3428 2017-10-03 05:00:00 2017-10-03 05:59:59
3428 2017-10-03 06:00:00 2017-10-03 06:09:19
Second example with:
tblDataId TimeStart TimeEnd
3430 2017-10-07 02:08:24 2017-10-07 14:09:30
Result:
tblDataId TSStart TSEnd
3430 2017-10-07 02:08:24 2017-10-07 02:59:59
3430 2017-10-07 03:00:00 2017-10-07 03:59:59
3430 2017-10-07 04:00:00 2017-10-07 04:59:59
3430 2017-10-07 05:00:00 2017-10-07 05:59:59
3430 2017-10-07 06:00:00 2017-10-07 06:59:59
3430 2017-10-07 07:00:00 2017-10-07 07:59:59
3430 2017-10-07 08:00:00 2017-10-07 08:59:59
3430 2017-10-07 09:00:00 2017-10-07 09:59:59
3430 2017-10-07 10:00:00 2017-10-07 10:59:59
3430 2017-10-07 11:00:00 2017-10-07 11:59:59
3430 2017-10-07 12:00:00 2017-10-07 12:59:59
3430 2017-10-07 13:00:00 2017-10-07 13:59:59
3430 2017-10-07 14:00:00 2017-10-07 14:09:30

Related

Pandas: merge two time series and get the mean values during the period when these two have overlapped time period

I got two pandas dataframes as following:
ts1
Out[50]:
soil_moisture_ids41
date_time
2007-01-07 05:00:00 0.1830
2007-01-07 06:00:00 0.1825
2007-01-07 07:00:00 0.1825
2007-01-07 08:00:00 0.1825
2007-01-07 09:00:00 0.1825
... ...
2017-10-10 20:00:00 0.0650
2017-10-10 21:00:00 0.0650
2017-10-10 22:00:00 0.0650
2017-10-10 23:00:00 0.0650
2017-10-11 00:00:00 0.0650
[94316 rows x 3 columns]
and the other one is
ts2
Out[51]:
soil_moisture_ids42
date_time
2016-07-20 00:00:00 0.147
2016-07-20 01:00:00 0.148
2016-07-20 02:00:00 0.149
2016-07-20 03:00:00 0.150
2016-07-20 04:00:00 0.152
... ...
2019-12-31 19:00:00 0.216
2019-12-31 20:00:00 0.216
2019-12-31 21:00:00 0.215
2019-12-31 22:00:00 0.215
2019-12-31 23:00:00 0.215
[30240 rows x 3 columns]
You could see that, from 2007-01-07 to 2016-07-19, only ts1 has the data points. And from 2016-07-20 to 2017-10-11 there are some overlapped time series. Now I want to combine these two data frames. During the overlapped period, I want to get the mean values over ts1 and ts2. During the non-overlapped period, (2007-01-07 to 2016-07-19 and 2017-10-12 to 2019-12-31), the values at each time stamp is set as the value from ts1 or ts2. So how can I do it?
Thanks!
Use concat with aggregate mean, if only one value get same ouput, if multiple get mean. Also finally DatatimeIndex is sorted:
s = pd.concat([ts1, ts2]).groupby(level=0).mean()
Just store the concatenated series first and then apply the mean. i.e. merged_ts = pd.concat([ts1, ts2]) and then mean_ts = merged_ts.group_by(level=0).mean()

Aggregate time from 15-minute interval to single hour in SQL

I have below table structure in SQL Server:
StartDate Start End Sales
==============================================
2020-08-25 00:00:00 00:15:00 291.4200
2020-08-25 00:15:00 00:30:00 401.1700
2020-08-25 00:30:00 00:45:00 308.3300
2020-08-25 00:45:00 01:00:00 518.3200
2020-08-25 01:00:00 01:15:00 247.3700
2020-08-25 01:15:00 01:30:00 115.4700
2020-08-25 01:30:00 01:45:00 342.3800
2020-08-25 01:45:00 02:00:00 233.0900
2020-08-25 02:00:00 02:15:00 303.3400
2020-08-25 02:15:00 02:30:00 11.9000
2020-08-25 02:30:00 02:45:00 115.2400
2020-08-25 02:45:00 03:00:00 199.5200
2020-08-25 06:00:00 06:15:00 0.0000
2020-08-25 06:15:00 06:30:00 45.2400
2020-08-25 06:30:00 06:45:00 30.4800
2020-08-25 06:45:00 07:00:00 0.0000
2020-08-25 07:00:00 07:15:00 0.0000
2020-08-25 07:15:00 07:30:00 69.2800
Is there a way to group above data into one hour interval instead of 15 minute interval?
It has to be based on start and end columns.
Thanks,
Maybe something like the following using datepart?
select startdate, DatePart(hour,start) [Hour], Sum(sales) SalesPerHour
from t
group by startdate, DatePart(hour,start)

SQL Server : get start time and end time with in the multiple night shift

How can I get the Start and End time of this list? I can add date to this time and can get by min and max but you can see row 3 have next day shift but it will come under same date because it is night shift
I have added normal day shift employee also get the logic right
EmployeeId ShiftDate ShiftStartTime ShiftEndTime
-----------------------------------------------------
20040 2017-11-01 21:00:00 23:00:00
20040 2017-11-01 23:00:00 00:30:00
20040 2017-11-01 00:30:00 06:00:00
20124 2017-11-01 09:00:00 16:30:00
20124 2017-11-01 16:30:00 22:00:00
20124 2017-11-01 22:00:00 22:30:00
I need it like below:
EmployeeId ShiftDate ShiftStartTime ShiftEndTime
----------------------------------------------------
20040 2017-11-01 21:00:00 06:00:00
20124 2017-11-01 09:00:00 22:30:00
In a commercial environment we solved this by attaching a FLAG to each shift. The Flag would indicate the 'Reporting Date' of the Shift...The Flag would have have a value of 1 if the 'Reporting / Administrative date' was the 'next' day. 0 for the same day. -1 for the previous day (which we never used...depends on your scenario)
I modified your table to show a possible SHIFTS table, which should also have a NAME column I guess (like Morning, Afternoon, Day, Night shift etc)
ReportFlag ShiftStartTime ShiftEndTime
1 21:00:00 23:00:00
1 23:00:00 00:30:00
0 00:30:00 06:00:00
0 09:00:00 16:30:00
0 16:30:00 22:00:00
1 22:00:00 22:30:00
Notice how I added 1 - to say that 'this shift' is actually considered to be on the 'next' day.
Then you can use your flag value 0,1 to add to DATE functions in your queries too

SQL Multiple record : Time Scheduler

I have problem about combining tables in store procedure.
Note : field "Time" is varchar
First table (tbTime)
Time
08:00:00
08:30:00
09:00:00
09:30:00
10:00:00
10:30:00
11:00:00
11:30:00
12:00:00
12:30:00
13:00:00
13:30:00
14:00:00
14:30:00
15:00:00
15:30:00
16:00:00
16:30:00
17:00:00
17:30:00
18:00:00
18:30:00
19:00:00
19:30:00
20:00:00
Second table (tbClassRsv)
select * from tbclassrsv where transdate='2014-02-05 00:00:00' and status<>'DEL'
transDate time until status studentCode tutor class description userID
2014-02-05 16:48:14 17:48:14 OPN ET-7201 ET-444 ROOM 01 try ADMIN
I want the result with condition schedule like this
Time Student
08:00:00 -
08:30:00 -
09:00:00 -
09:30:00 -
10:00:00 -
10:30:00 -
11:00:00 -
11:30:00 -
12:00:00 -
12:30:00 -
13:00:00 -
13:30:00 -
14:00:00 -
14:30:00 -
15:00:00 -
15:30:00 -
16:00:00 -
16:30:00 ET-7201
17:00:00 ET-7201
17:30:00 ET-7201
18:00:00 ET-7201
18:30:00 -
19:00:00 -
19:30:00 -
20:00:00 -
Thanks for reading or answer ^_^
GBU
I`ve tried this
select t.time,
isnull(
(select c.studentCode
from tbclassrsv c
where c.transdate='2014-02-05 00:00:00'
and c.class='ROOM 01'
and c.status<>'DEL'
and t.time>=c.time
and t.time<=c.until
),'-') [Student]
The result is....
Time Student
08:00:00 -
08:30:00 -
09:00:00 -
09:30:00 -
10:00:00 -
10:30:00 -
11:00:00 -
11:30:00 -
12:00:00 -
12:30:00 -
13:00:00 -
13:30:00 -
14:00:00 -
14:30:00 -
15:00:00 -
15:30:00 -
16:00:00 -
16:30:00 -
17:00:00 ET-7201
17:30:00 ET-7201
18:00:00 -
18:30:00 -
19:00:00 -
19:30:00 -
20:00:00 -
Try this. you were not converting your varchar times to datetime so that your time comparisons would work.
select t.time,
isnull(
(select c.studentCode
from tbClassRsv c
where c.transdate='2014-02-05 00:00:00'
and c.class='ROOM 01'
and c.status<>'DEL'
and DateAdd(MINUTE, 30, Convert(datetime, t.time))>= Convert(datetime, c.time)
and Convert(datetime, t.time) <= Convert(datetime, c.until)
),'-') from [tbTime] t
What you need to do is round c.time down to the nearest 30 minutes interval, and round c.until up to the nearest interval. This way your where clause will have the correct range.
To do the rounding you will need to convert the times to datetime which you can do like so:
CAST(CONVERT(varchar,THE_TIME_AS_VARCHAR,121) AS datetime)
Then you can round down to the nearest 30 minutes like so:
DATEADD(mi, DATEDIFF(mi, 0, THE_TIME_AS_DATETIME)/30*30, 0)
And round up like so:
DATEADD(mi, DATEDIFF(mi, 30, THE_TIME_AS_DATETIME)/30*30, 0)
Applying all that to your existing code would give you this:
select t.time,
isnull(
(select c.studentCode
from tbclassrsv c
where c.transdate='2014-02-05 00:00:00'
and c.class='ROOM 01'
and c.status<>'DEL'
and t.time>= DATEADD(mi, DATEDIFF(mi, 0, CAST(CONVERT(varchar,c.time,121) AS datetime))/30*30, 0)
and t.time<= DATEADD(mi, DATEDIFF(mi, 30, CAST(CONVERT(varchar,c.until,121) AS datetime))/30*30, 0)
),'-') [Student]

How to Split Time and calculate time difference in sql server 2005?

i want to split the time and calculate time difference using sql server 2005
my default output is like this:
EnrollNo AttDateFirst AttDateLast
111 2011-12-09 08:46:00.000 2011-12-09 08:46:00.000
112 2011-12-09 08:40:00.000 2011-12-09 17:30:00.000
302 2011-12-09 09:00:00.000 2011-12-09 18:30:00.000
303 2011-12-09 10:00:00.000 2011-12-09 18:35:00.000
I want my new output to be like this:
Enroll No ..... FirtTime LastTime Time Diff
111 ..... 8:46:00 8:45:00 00:00:00
112 ..... 8:30:00 17:30:00 9:00:00
302 ..... 9:00:00 18:30:00 9:30:00
303 ..... 10:00:00 18:35:00 8:35:00
You can use this query:
select EnrollNo, convert(varchar, AttDateFirst, 8) as FirstTime,
convert(varchar, AttDateLast, 8) as LastTime,
convert(varchar, AttDateLast - AttDateFirst, 8) as [Time Diff]
from YourTable
to return the following results:
EnrollNo FirstTime LastTime Time Diff
----------- ------------------------------ ------------------------------ ------------------------------
111 08:46:00 08:46:00 00:00:00
112 08:30:00 17:30:00 09:00:00
302 09:00:00 18:30:00 09:30:00
303 10:00:00 18:35:00 08:35:00
you can use
select DATEDIFF(day,2007-11-30,2007-11-20) AS NumberOfDays,
DATEDIFF(hour,2007-11-30,2007-11-20) AS NumberOfHours,
DATEDIFF(minute,2007-11-30,2007-11-20) AS NumberOfMinutes from
test_table
to split u can use
substring(AttDateFirst,charindex(' ',AttDateFirst)+1 ,
len(AttDateFirst)) as [FirstTime]