Interval aggregation of 5 minutes for last 24 hours in database - sql-server

I am trying to aggregate the data for last 24 hours on 5 min interval basis. I had written following query:
select
DATEADD(MINUTE, DATEDIFF(MINUTE, '2000', t.datetime) / 5 * 5, '2000')
as datetimevalue,
cast(sum(t.value) as decimal(10,2)) as value
from
dbo.data t
where
t.datetime <= '2020-09-12 19:23:00.000'
and t.datetime > DATEADD(day,-1,'2020-09-12 19:23:00.000')
group by
DATEADD(MINUTE, DATEDIFF(MINUTE, '2000', t.datetime) / 5 * 5, '2000')
order by
datetimevalue asc
The result is returned like this:
datetimevalue value
------------------------------------
2020-09-12 18:45:00.000, 54227.16
2020-09-12 18:50:00.000, 53681.54
2020-09-12 18:55:00.000, 49379.01
2020-09-12 19:00:00.000, 50751.53
2020-09-12 19:05:00.000, 55033.14
2020-09-12 19:10:00.000, 55858.37
2020-09-12 19:15:00.000, 54236.57
2020-09-12 19:20:00.000, 26731.36
I need aggregation of last 5 minute starting from current timestamp insteead of above which is aggregating last 3 minutes and then 5 minutes after that.
For example
datetimevalue value
--------------------------------------
2020-09-12 19:03:00.000, 22444.47
2020-09-12 19:08:00.000, 45674.46
2020-09-12 19:13:00.000, 35737.23
2020-09-12 19:18:00.000, 34675.34
Any assistance appreciated.

You need to calculate the offset to the aggregation time window (5 minutes), substract it while calculating values and the add it again to the final times:
DECLARE #dt DATETIME = GETDATE()
DECLARE #offset INT = (DATEDIFF(SECOND, CAST(CAST(#dt AS DATE) AS DATETIME), #dt) % (60 * 5)) / 60 * 60
-- In case you want an offset in seconds
--DECLARE #diff INT = DATEDIFF(SECOND, CAST(CAST(#dt AS DATE) AS DATETIME), #dt) % (60 * 5)
SELECT DATEADD(SECOND, #offset, datetimevalue) AS datetimevalue, value
FROM (
SELECT
DATEADD(MINUTE, DATEDIFF(MINUTE, '2000', DATEADD(SECOND, -#offset, t.DATETIME)) / 5 * 5, '2000') AS datetimevalue
,cast(sum(t.value) AS DECIMAL(10, 2)) AS value
FROM dbo.data t
WHERE t.DATETIME <= #dt
-- in case you want only for last 24 hours
-- AND t.DATETIME > DATEADD(DAY, - 1, #dt)
-- in case if you want to include offset in last timestamp
AND t.DATETIME > DATEADD(SECOND, -#offset, DATEADD(DAY, - 1, #dt))
GROUP BY DATEADD(MINUTE, DATEDIFF(MINUTE, '2000', DATEADD(SECOND, -#offset, t.DATETIME)) / 5 * 5, '2000')
) T
ORDER BY datetimevalue DESC

Related

SQL Server: Calculate Four Weeks From a Month

I need a simple solution to get 4 weeks for a month based on current date (each week starting from Monday - Friday).
For each week I need to update a table that already has current date and place a counter from Week 1 - 4 and continue to the following month starting from Week 6 - 8. and start from the beginning after week 8.
The query below is returning week number but for 7 days:
can I use something similar just for 5 days?
DECLARE #MyDate DATETIME = '2020-08-03'
--This assumes the weeks starts from Monday - Sunday
DECLARE #WeekNumber INTEGER = (DATEPART(DAY, DATEDIFF(DAY, 0, #MyDate)/7 * 7)/7 +1)
SELECT #WeekNumber
The previous answer was not useful so I got rid of it. This should do what you're looking for
declare #date datetime= '2020-08-03';
select dateadd(d, -4, dt.dt) start_dt,
dt.dt end_dt,
row_number() over (order by v.n) n
from
(select datefromparts(year(#date),month(#date),1) first_dt) fd
cross apply
(select datediff(week, 0, fd.first_dt) wk_diff) wd
cross apply
(values (1),(2),(3),(4),(5),(6)) v(n)
cross apply
(select dateadd(d, -((datepart(weekday, fd.first_dt) + 1 + ##datefirst) % 7), fd.first_dt) calc_dt) calc_dt
cross apply
(select dateadd(d, (v.n-1)*7, calc_dt) dt) dt
where
dt.dt>=fd.first_dt;
Results
start_dt end_dt n
2020-08-03 2020-08-07 1
2020-08-10 2020-08-14 2
2020-08-17 2020-08-21 3
2020-08-24 2020-08-28 4
2020-08-31 2020-09-04 5

Not getting any rows from query but there are rows available in the table

AND (
(datediff(DAY,getdate(), '2020-07-14 00:00:00.000') = 5)
OR (
datediff(DAY,getdate(), A.HX_RELIEVING_DT) BETWEEN 0 AND 4
AND '2020-04-17 20:36:53.000' >= GETDATE()-1
)
)
This is the output I want for relieving date and last updated time but I am unable to get this
EMPLID LOCATION SUPERVISOR_ID HX_RELIEVING_DT LASTUPDDTTM
-- SINGAPORE --- 2020-07-14 00:00:00.000 2020-04-17 20:36:53.000
I believe you tried to write if #MyDate is past:
AND ((DATEDIFF(DAY, #MyDate, GETDATE()) = 5) OR (DATEDIFF( DAY, A.HX_RELIEVING_DT, GETDATE()) BETWEEN 0 AND 4 AND DATEADD(DAY, -1, GETDATE()) <= #MyDate))
If #MyDate is future:
AND ((DATEDIFF(DAY, GETDATE(), #MyDate) = 5) OR (DATEDIFF(DAY, GETDATE(), A.HX_RELIEVING_DT) BETWEEN 0 AND 4 AND DATEADD(DAY, 1, GETDATE()) <= #MyDate))
Last condition from your WHERE clause is basically filtering your record from the output.
AND '2020-04-17 20:36:53.000' >= GETDATE()-1
A date from month "April" can not be bigger than a date value from July, right? You can check the values you are using in different condition in WHERE clause with this below query. You will get your issue automatically.
SELECT *,
datediff(DAY,getdate(), '2020-07-14 00:00:00.000'),
datediff(DAY,getdate(), A.HX_RELIEVING_DT),
GETDATE()-1
FROM your_table A

Add 11 hours to datetime2 colum in SQL Server

I have a date and time column like this:
I want to add Time4 + 11:00 hours = 00:53:27:967 + 11:00:00 = 11:53:27:967
and then append it to timestamp of Time1 column to get
2018-10-19 11:53:27:967.
Below is the procedure I followed:
-- Step 1 Trim the Time1 to display only the date
SELECT time1, time4, LEFT(CAST(Time1 AS DATETIME2), LEN(time1) - 9) AS Time5
FROM table1
And got the this output:
--Step 2 Add Time4 + 11
SELECT time4 + '11:00:00.0000000' AS Time6
FROM DU_GPSTime_2
I am failing in above step.
Final step looks simple if step 2 is fixed.
--Step 3 Combine time5 + time6
SELECT time7 = time5 + time6
FROM table1
Just use a combination of DATEADD and DATEDIFF
DATEADD( hh, 11, DATEADD( ms, DATEDIFF( ms, 0, Time4), Time1))
Follow example
SELECT Time5, DATEADD(HOUR, 11, CONVERT(time, Time6)) as Time6, CONCAT(CONVERT (date, Time5),' ',DATEADD(HOUR, 11, CONVERT(time, Time6))) AS Time10 FROM TB_EXEMPLO

DATEADD MINUTES Between Range MSSQL

I am having some difficulty in trying to figure out something, lets say I have a date and time;
And I want to add 180 minutes to it so;
SELECT DATEADD(MINUTE,180,'2018-05-24 15:00')
This would give me answer of "2018-05-24 18:00" but I want to do it in a range so ADD the minutes if you are between 09:00 - 17:00 so something like this;
SELECT DATEADD(MINUTES,180,'2018-05-24 15:00') WHERE '2018-05-24 15:00' BETWEEN '2018-05-24 09:00' AND '2018-05-24 17:00'
So the answer to this would be "2018-05-25 10:00"
Was hard, but this should work for all your cases. This solution works for any amount of (positive) minutes and result will always be inside the parametrized hours, adding the corresponding amount of days.
DECLARE #RangeHourStart INT = 9
DECLARE #RangeHourEnd INT = 17
DECLARE #MinutesToAdd INT = 120
DECLARE #Date DATETIME = '2018-05-24 15:00'
SELECT
FinalDate = CASE
WHEN -- When final hour exceeds the range hour
DATEPART(HOUR, #Date) * 60 +
DATEPART(MINUTE, #Date) +
#MinutesToAdd % ((#RangeHourEnd - #RangeHourStart) * 60) > #RangeHourEnd * 60
THEN
DATEADD(HOUR, -1 * (#RangeHourStart - 1),
DATEADD(DAY, 1,
DATEADD(MINUTE, #MinutesToAdd % ((#RangeHourEnd - #RangeHourStart) * 60),
DATEADD(
DAY,
#MinutesToAdd / ((#RangeHourEnd - #RangeHourStart) * 60),
#Date))))
ELSE
DATEADD(MINUTE, #MinutesToAdd % ((#RangeHourEnd - #RangeHourStart) * 60),
DATEADD(
DAY,
#MinutesToAdd / ((#RangeHourEnd - #RangeHourStart) * 60),
#Date))
END
I made it so you don't need to hard-code any value.
This doesn't look particularly pretty, however...
USE Sandbox;
GO
CREATE TABLE Times (DateNTime datetime2(0));
INSERT INTO Times
VALUES ('20180520 10:00:00'),
('20180520 15:20:00'),
('20180521 09:32:00'),
('20180521 14:17:00'),
('20180522 16:54:00'),
('20180523 12:46:00'),
('20180524 15:32:00');
GO
SELECT *
FROM Times;
GO
SELECT T.DateNTime,
CASE WHEN CONVERT(time,T.DateNTime) <= '14:00' THEN DATEADD(MINUTE, 180,T.DateNTime)
ELSE DATEADD(MINUTE, 180 - DATEDIFF(MINUTE,T.DateNTime,DATEADD(HOUR,17,DATEADD(DAY, DATEDIFF(DAY, 0, T.DateNTime),0))), DATEADD(HOUR,9,DATEADD(DAY, DATEDIFF(DAY, 0, T.DateNTime) + 1,0))) END
FROM Times T;
GO
DROP TABLE Times;
you can try this:
DECLARE #input DATETIME='2018-05-24 15:00'
DECLARE #min INT=180
SELECT CASE WHEN DATEADD(MINUTE,#min,#input)>DATEADD(HOUR, 17,DateAdd(Day, Datediff(Day,0, #input), 0))
THEN DATEADD(MINUTE,
DATEDIFF(MINUTE,
DATEADD(HOUR, 17,
DATEADD(Day,
DATEDIFF(Day,0, #input),
0)
),
DATEADD(MINUTE,#min,#input)),
DATEADD(Hour,9,
DATEADD(Day,1,
DateAdd(Day,
Datediff(Day,0, #input),
0)
)
)
)
ELSE DATEADD(MINUTE,#min,#input)
END

sql not in between two weekdays and times

I have a query that monitors connection process. Now I'm stuck and need to set a proper monitoring for weekday and time range.
The process starts on Sunday 22:00, and goes down for 5 min. at 21:55 - every day to Friday. (not goes up from Friday 21:55 till 22:00 on Sunday)
Below is the SQL Query I tried:
IF CASE
WHEN (100 * DATEPART(hh, GETDATE()))
+ DATEPART(MINUTE, GETDATE())
BETWEEN 2155 AND 2200 -- Monitoring for whole day, wen connection is up
AND DATEPART(dw,GETDATE()), (100 * DATEPART(hh, GETDATE()))
+ DATEPART(MINUTE, GETDATE())
NOT BETWEEN (5, 2155) AND (0, 2200) --except trough Friday night to Sunday (weekdays and time).
THEN 1 ELSE 0 END = 0
You needed to add some SELECT statements into the parts of the case where you were getting the values to range between. Try this:
SELECT
CASE
WHEN(100 * DATEPART(hh, GETDATE())) + DATEPART(MINUTE, GETDATE()) -- = 731
BETWEEN 2155 AND 2200 -- Monitoring for whole day, wen connection is up
AND (
(
SELECT
DATEPART(dw, GETDATE())
) NOT BETWEEN(5) AND(0)
AND
(
SELECT
(100 * DATEPART(hh, GETDATE())) + DATEPART(MINUTE, GETDATE())
) NOT BETWEEN(2155) AND(2200)
)
THEN 1
ELSE 0
END;
The first calculation equals 731 so looking at the query I would except it to return '0' which it does

Resources