Add 11 hours to datetime2 colum in SQL Server - 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

Related

Interval aggregation of 5 minutes for last 24 hours in database

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

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

How to do sorting by Day and Hour field?

I have a string value as 07052018080504623
It represents MM DD YYYY HH MM SS MS
means
MM = 07, DD = 05, YYYY=2018, HH = 08, MM=05 , SS= 04, MS = 623
Now I have a table defined as
declare #t table (WorkRequestId varchar(100))
insert into #t values
('07052018080504623'),('07062018012756663'),('07062018020148130'),('07062018095201231'),
('07062018102203805'),('07062018103718059'),('07062018110304836'),('07062018115356135'),
('07062018120624983'),('07062018124035480'),('07062018080504623'),('07062018070504623')
select
*
from #t
The records should be sorted in ascending order such that
WorkRequestId
07052018080504623
07062018095201231
07062018102203805
07062018103718059
07062018110304836
07062018115356135
07062018120624983
07062018124035480
07062018012756663
07062018020148130
The cutoff time is 8PM of previous day to 19:59:59 PM of next day.
In our example, 05 is previous day while 06 is next day.
Also no transaction happens between 1AM - 7:59:59 AM of next day. It starts again from 8AM of next day and continues till
19:59:59 PM.
So when we encounter 07062018012756663, the DD=06 and HH = 01. It means 13HRs (i.e. 1PM) of 6th. Same for 07062018020148130 where DD=06 and HH = 02 (i.e. 2PM or 14Hrs).
But 07062018095201231 where DD=06 and HH = 09 means 9AM of 6th.
That is why
07062018095201231 comes before 07062018012756663 and 07062018020148130
while ordering
My attempt so far (not correct yet)
select
*
,DY=SUBSTRING([WorkRequestId],3,2)
,HH = SUBSTRING([WorkRequestId],9,2)
,CurrentDY=CONVERT(varchar(2), getdate(), 103)
from #t
order by left([WorkRequestId],8) +
cast(iif(
SUBSTRING([WorkRequestId],3,2) = '6',--CONVERT(varchar(2), getdate(), 103),
iif(cast(SUBSTRING([WorkRequestId],9,2) as int) between 1 and 7,
cast(SUBSTRING([WorkRequestId],9,2) as int)+12,SUBSTRING([WorkRequestId],9,2)),
cast(SUBSTRING([WorkRequestId],9,2)as varchar(4)))as varchar(20))
+right([WorkRequestId],7)
So, I guess you should realize by now that storing dates as strings (and in fact, storing anything in the wrong data type) is bad practice.
The correct solution is to change the database structure to hold that data as DateTime2 instead of a string. However, assuming this can't be done for some reason, you can get the results you want by converting the string values to datetime2, adding 12 hours where the hour is between 1 a.m. and 8 a.m., and sort by that date.
I've written my suggestion in a cumbersome way because I wanted to show every part of the process - I've used 3 common table expression though if can be done in a single query - again, that's just to illustrate every step of the solution:
;WITH CTEDateParts AS -- break down the string to it's parts
(
SELECT WorkRequestId,
SUBSTRING(WorkRequestId, 5, 4) As Year,
SUBSTRING(WorkRequestId, 1, 2) As Month,
SUBSTRING(WorkRequestId, 3, 2) As Day,
SUBSTRING(WorkRequestId, 9, 2) As Hour,
SUBSTRING(WorkRequestId, 11, 2) As Minute,
SUBSTRING(WorkRequestId, 13, 2) As Second,
SUBSTRING(WorkRequestId, 15, 3) As Millisecond
FROM #t
), CTEDates AS -- create datetime values from the string parts
(
SELECT WorkRequestId,
CAST(Year +'-'+ Month +'-'+ Day +'T'+
Hour +':'+ Minute +':'+ Second +'.'+ Millisecond As DateTime2(7)) As DateValue
FROM CTEDateParts
), CTEFixedDates AS -- add 12 hours for hours between 1 and 8 a.m.
(
SELECT WorkRequestId,
DateValue,
CASE WHEN DATEPART(HOUR, DateValue) >= 1 AND DATEPART(HOUR, DateValue) <= 8 THEN
DATEADD(Hour, 12, DateValue)
ELSE
DateValue
END As FixedDate
FROM CTEDates
)
-- finally, select order by the FixedDate column
SELECT WorkRequestId
FROM CTEFixedDates
ORDER BY FixedDate
Results:
WorkRequestId
07052018080504623
07062018095201231
07062018102203805
07062018103718059
07062018110304836
07062018115356135
07062018120624983
07062018124035480
07062018012756663
07062018020148130
07062018070504623
07062018080504623
You can try the following:
select
*
from #t
order by left (WorkRequestId, 8) + (case when SUBSTRING(WorkRequestId, 9,2) between '01' and '07' then CAST(SUBSTRING(WorkRequestId, 9,2) + 12 AS CHAR(2)) else SUBSTRING(WorkRequestId, 9,2) end) + SUBSTRING(WorkRequestId, 11,7)

Add a number (13) to the month and change the day to the 1st of that month

I am sure this one is simple but I am having a difficult time figuring it out. I am trying to add 13 months to a date and that resulting month needs to default to the 1st day of the month.
Example:
Date: 1/25/2016
Query results: 2/1/2017
Here is the query I am using:
SELECT Dateadd(month,13,getdate())
This should work for you. Just replace GETDATE() with your date.
select dateadd(month, datediff(month, 0, dateadd(month, 13, GETDATE())), 0)
SQL 2012+
SELECT DATEADD(DAY, 1, EOMONTH(GETDATE(), 12))
You can just construct the date from the constituent parts, by adding 1 year + 1 month and forcing the day part to 1 (and taking care of the special case of month = 12), like this:
select DATEFROMPARTS (
year(getdate()) + case when month(getdate()) = 12 then 2 else 1 end,
case when month(getdate()) = 12 then 1 else month(getdate()) + 1 end,
1
)

Select records created in a 24 hour time-frame

I'm trying to query our database to find all records that were created between 6am yesterday and 6am today. This will be run in a report at any point during the day so set times/dates are useless.
I have this so far:-
SELECT * FROM DaySummaryDetail DSD
WHERE DSD.FromDateTime BETWEEN DATEADD(DAY, -1, GetDate())
AND DATEADD(Day, 1, GetDate())
But obviously this only works for 24 hours ago from right now until right now. I can't figure out how to apply a time as well as date.
Every example I find online seems slightly different and uses set dates/times ie, >= 20/02/2015 06:00:00.
I normally use Oracle SQL which would simply work using this:-
ptt.mod_date_time >= TRUNC (SYSDATE - 1) - 2 / 24
AND ptt.mod_date_time <= TRUNC (SYSDATE - 1) + 22 / 24
This would return results from 10pm to 10pm but the format appears totally different in SQL Server.
You can get the datetime values you are after by doing the following:
SELECT DATEADD(HOUR,6,CONVERT(DATETIME, CONVERT(DATE ,GETDATE()))) Today6AM,
DATEADD(HOUR,-18,CONVERT(DATETIME, CONVERT(DATE ,GETDATE()))) Yesterday6AM
By doing this: CONVERT(DATE ,GETDATE()) you are stripping off the time portion of today's date. Converting it back to datetime gives you midnight for today.
The query adds 6 hours to midnight of the current day for 6am today and subtracts 18 hours from midnight of the current day to give you 6am on the previous day.
Output:
Today6AM Yesterday6AM
================================================
2015-02-20 06:00:00.000 2015-02-19 06:00:00.000
So adding that to your query:
SELECT *
FROM DaySummaryDetail DSD
WHERE DSD.FromDateTime
BETWEEN DATEADD(HOUR,-18,CONVERT(DATETIME, CONVERT(DATE ,GETDATE())))
AND DATEADD(HOUR,6,CONVERT(DATETIME, CONVERT(DATE ,GETDATE())))
DECLARE #StartTimestamp datetime
DECLARE #EndTimestamp datetime
DECLARE #HourPartOfSearchRange nvarchar(6)
SET #HourPartOfSearchRange = ' 06:30'
SET #StartTimestamp =
CAST((CONVERT(varchar(11), DATEADD(DAY,-1,#CurrentUTCDateTime), 106) + #HourPartOfSearchRange) AS datetime)
SET #EndTimestamp =
CAST((CONVERT(varchar(11), #CurrentUTCDateTime, 106) + #HourPartOfSearchRange) AS datetime)
SELECT * FROM dbo.Test Where Timestamp Between #StartTimestamp AND #EndTimestamp
today 6am is
dateadd(hour,6,cast(cast(getdate() as date) as datetime))
cast(getdate() as date) truncates the timepart, cast it back as datetime because dateadd won't add hours otherwise and add 6hours
One solution would be like so:
select *
from DaySummaryDetail DSD
where DSD.FromDateTime between cast(cast(cast(getdate()-1 as date) as varchar(30)) + ' 06:00:00.000' as datetime)
and cast(cast(cast(getdate() as date) as varchar(30)) + ' 06:00:00.000' as datetime)
This should help ...
SELECT DATEADD( hour, 6, CAST(CAST(GETDATE(), AS Date) AS DateTime) ) AS 'Today#6am'
SELECT DATEADD( hour, 6, CAST(CAST(GETDATE()-1, AS Date) AS DateTime) ) AS 'Yesterday#6am'
In SQL Server 2012 you can use SMALLDATETIMEFROMPARTS to construct a datetime value that is today at 6am like this:
SMALLDATETIMEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), DAY(GETDATE()), 6, 0)
Output: 2015-02-20 06:00:00
then you can use the above expression in place of GETDATE() in the WHERE clause:
DECLARE #TodayAt6AM DATETIME = SMALLDATETIMEFROMPARTS(YEAR(GETDATE()),
MONTH(GETDATE()),
DAY(GETDATE()),
6,
0)
SELECT *
FROM DaySummaryDetail DSD
WHERE DSD.FromDateTime BETWEEN DATEADD(DAY, -1, #TodayAt6AM) AND
DATEADD(Day, 1, #TodayAt6AM)

Resources