Update time portion of a datetime in SQL Server - sql

I have a DateTime variable in SQL Server..I have the below code to check for weekend and then subtract the days to make it Friday. Now I also want to set the time of this new Datetime as 5 PM on the Friday. Can someone please tell me how can I achieve this.
if(DATENAME(DW, #EndDate) = 'Sunday')
Begin
Set #EndDate = (SELECT DATEADD(DAY, -2, #EndDate))
End
if(DATENAME(DW, #EndDate) = 'Saturday')
Begin
Set #EndDate = (SELECT DATEADD(DAY, -1, #EndDate))
End
End
Thanks

You can add 17 hours:
Set #EndDate = DATEADD(HOUR, 17, DATEADD(DAY, -1, #EndDate))
I have no idea why you have phrased this logic using a subquery. It is not necessary.
If your data already has a time component, then cast to a date first to get rid of the time component, then back to a datetime:
Set #EndDate = DATEADD(HOUR, 17, DATEADD(DAY, -1, CONVERT(datetime, CONVERT(DATE, #EndDate))))

select cast(CONVERT(varchar(12),GETDATE()) + '17:00' as datetime)

Related

Accumulating data from previous year

I'm having trouble with finding a solution for below SQL-query. My first query should and does the trick of accumulating amount of last year's data.
CASE
WHEN rehuv.VER_DATUM >= dateadd(year, -1, dateadd(month, -datepart(month, #STARTDATE) + 1, #STARTDATE))
AND rehuv.VER_DATUM <= DATEADD(year, -1, #ENDDATE) THEN rehuv.BELOPP ELSE 0
END AS PREVIOUS_YEAR_ACC
But when I try to accumulate data within a specific time interval (I want the same time interval as #startdate -> #enddate but one year backwards). Sql-query:
CASE
WHEN rehuv.VER_DATUM >= DATEADD(year, -1, #STARTDATE)
AND rehuv.VER_DATUM <= DATEADD(year, -1, #ENDDATE) THEN rehuv.BELOPP ELSE 0
END AS PREVIOUS_YEAR_MONTH
Thank you in advance!
Best regards,
Simon
If you want the monthly sum of last year, you can try this:
DECLARE #STARTDATE DATETIME;
DECLARE #ENDDATE DATETIME;
SET #STARTDATE='2015-1-1';
SET #ENDDATE='2015-5-1';
DECLARE #LAST_YEAR DATE;
SET #LAST_YEAR = DATEADD(YEAR, -1, DATEADD(DAY,
DATEPART(DAYOFYEAR, GETDATE())*-1+1, CONVERT(DATE, GETDATE())));
SELECT DATEADD(MONTH, DATEPART(MONTH, VER_DATUM), #LAST_YEAR) MONTH, SUM(CASE
WHEN REHUV.VER_DATUM >= DATEADD(YEAR, -1, #STARTDATE)
AND REHUV.VER_DATUM <= DATEADD(YEAR, -1, #ENDDATE)
THEN REHUV.BELOPP ELSE 0
END ) AS PREVIOUS_YEAR_MONTH
FROM REHUV
GROUP BY DATEPART(MONTH, VER_DATUM)

How do I find data from this day exactly one year ago?

Right now I have:
year(epe_curremploymentdate) = year(DATEADD(year, -1, SYSDATETIME()))
But that is giving me everything from last year. All I want is the data from today's date, one year ago.
It should be:
epe_curremploymentdate = DATEADD(year, -1, GETDATE())
Don't check for year in your where clause.
EDIT:
Simple: use
cast(epe_curremploymentdate AS DATE) = cast(DATEADD(year, -1,
GETDATE()) AS DATE)
That is, if you are using SQL Server 2008 and above.
This should get you to where you need to go:
Declare #StartDate datetime, #EndDate datetime
-- #StartDate is midnight on today's date, last year
set #StartDate = Convert(date, (DATEADD(year, -1, getdate())))
set #EndDate = DATEADD(Day, 1, #StartDate)
select *
from YourTable
where epe_curremploymentdate >= #StartDate
and epe_curremploymentdate < #EndDate
-- This where clause will get you everything that happened at any time
-- on today's date last year.
Date today:
select getdate()
date one year ago:
select dateadd(year, -1, getdate())
Date one year and one day ago:
select dateadd(d, -1 , dateadd(year, -1, getdate()))
UPDATE:
select *
from
epe_curremploymentdate = dateadd(year, -1, CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME))
This will give you a list of all employees who started working exactly from a year ago.
Hope this helps!!!
If you have other fields that show as datetime with the time part as 00:00:00.000, to do joins you can use the below
dateadd(yy,-1,datediff(d,0,getdate()))
epe_curremploymentdate = DATEADD(year, -1, GETDATE())

sql date parameter in query

I've got a query and I want to add parameters to calculate the moving annual (the figures for the last 12 months). I'm trying to subtract 12 months from today, so if for instance today is 1 August 2012 then my #StartDate should be '2011-09-01' and my #EndDate should be '2012-08-31'. So how do I change set my parameters to accommodate this?
declare #StartDate DATE
declare #EndDate DATE
SET #StartDate = DATEADD(MONTH, -12, '2012-08-01')
SET #EndDate = DATEADD(MONTH, +1, '2012-08-01')
DECLARE
#InputDate DATE,
#StartDate DATE,
#EndDate DATE
SET
#InputDate = '2012-08-01'
SET
#StartDate = DATEADD(MONTH, DATEDIFF(MONTH, 0, #InputDate) - 11, 0)
SET
#EndDate = DATEADD(DAY, -1, DATEADD(MONTH, 12, #StartDate))
EDIT:
However, I do not recomend using '2011-09-01' to '2012-08-31' as a representation of a year. Instead, use '2011-09-01' to '2012-09-01' in the following way...
WHERE
table.dateField >= '2011-09-01'
AND table.dateField < '2012-09-01'
This works for all Date and DateTime data types. Even if the value in dateField is 2:30pm on 31st August, this will still work. It's a one size fits all approach and makes it much more difficult to make mistakes on date and time boundaries.
This was a few years ago but still not answered properly. The poster wants to find 12 months back from today, where "today" is dynamic. All prior answers start with a hard-coded start date instead of GETDATE()
DECLARE
#StartDate datetime,
#EndDate datetime
Set #StartDate = DATETIMEFROMPARTS(YEAR(GETDATE())-1, MONTH(GETDATE()), DAY(GETDATE()), 0, 0, 0, 0); Use midnight or a time that matches your business case.
Set #EndDate = DATETIMEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), DAY(GETDATE()), 23, 59, 59, 0); -- modify to match the times you are looking for.
Select * from Mydbase
WHERE
table.dateField between #StartDate and #EndDate
Add this after your last SET command:
SET #EndDate = DATEADD(DAY, -1, #EndDate)
Or substitute the 2nd SET by:
SET #EndDate = DATEADD(DAY, -1,DATEADD(MONTH, +1, '2012-08-01'))
try tiis:
declare #Date DATE='2012-08-05'
select convert(date,DateAdd(Month, DateDiff(Month, 0, #Date)-11,0)) StartDate ,
convert(date,DateAdd(day,-1,DateAdd(Month,1,
DateAdd(Month, DateDiff(Month, 0, #Date),0)))) EndDate
result:
StartDate EndDate
2011-09-01 2012-08-31

Set time portion of a datetime variable

I am working on a query that will be an automated job. It needs to find all the transactions between 8 PM and 8 PM for the last day. I was thinking of doing something like this
DECLARE #start_date DATETIME
DECLARE #end_date DATETIME
SET #start_date = DATEADD(DAY, -2, GETDATE())
SET #end_date = DATEADD(DAY, -1, GETDATE())
For an automated query this works good at figuring out the date portion. But the TIME portion of the variable is the current time that the query executes. Is there a quick simple way to hard code the time portion of both variables to be 8:00 PM?
DECLARE #start_date DATETIME
DECLARE #end_date DATETIME
SET #start_date = DATEADD(hour, 20, DATEDIFF(DAY, 2, GETDATE()))
SET #end_date = #start_date + 1
select #start_date, #end_date
This will also work:
DECLARE #start_date datetime
DECLARE #end_date datetime
SET #start_date = LEFT(CONVERT(nvarchar, DATEADD(DAY, -2, GETDATE()), 120), 11) + N'20:00:00'
SET #end_date = #start_date + 1
select #start_date, #end_date
Although cyberkiwi's answer is very clever! =)
I needed to pull a date from the database and append 3:00 Pm to it. I did it this way
select dateadd(hour, 15, datediff(day, 0, myDatabaseDate))
from dbo.myDatabaseTable
where myDatabaseId = 1
The result that it returned was 2017-10-01 15:00:00.000. The date in the database is 2017-10-01. The solution that I proposed was to keep my current date. I added 0 days to my existing date. I gave it 15:00 hours and it worked like a charm.
In case of just updating a particular part of the datetime you can use SMALLDATETIMEFROMPARTS like:
UPDATE MyTable
SET MyDate = SMALLDATETIMEFROMPARTS(YEAR(MyDate), MONTH(MyDate), DAY(MyDate), <HoursValue>, <MinutesValue>)
In other cases it may be required to copy parts of datetime to other or update only certain parts of the datetime:
UPDATE MyTable
SET MyDate = SMALLDATETIMEFROMPARTS(YEAR(MyDate), MONTH(MyDate), DAY(MyDate), DATEPART(hour, MyDate), DATEPART(minute, MyDate))
Refer SQL Server Date/Time related API references for more such functions
DECLARE #start_date DATETIME = DATEADD(HOUR, 20, DATEADD(MINUTE, 00, CONVERT(DATETIME, CONVERT(DATE, GETDATE())))) - 2
DECLARE #end_date DATETIME = DATEADD(HOUR, 20, DATEADD(MINUTE, 00, CONVERT(DATETIME, CONVERT(DATE, GETDATE())))) - 1
Notes:
GETDATE() + X is the equivalent of DATEADD(DAY, X, GETDATE()).
Converting a DATEIME to a DATE and then back to a DATETIME again sets the time to midnight i.e. 00:00:00.000.
Seperate SET and DECLARE statements are unnecessary, but just in case it helps later, variables may be set as part of a SELECT statement too.
I had to do something similar, create a procedure to run from a certain time the previous day to a certain time on the current day.
This is what I did to set the start date to 16:30 on the previous day, basically subtract the parts you don't want to get them back to 0 then add the value that you want it to be.
-- Set Start Date to previous day and set start time to 16:30.00.000
SET #StartDate = GetDate()
SET #StartDate = DateAdd(dd,- 1, #StartDate)
SET #StartDate = DateAdd(hh,- (DatePart(hh,#StartDate))+16, #StartDate)
SET #StartDate = DateAdd(mi,- (DatePart(mi,#StartDate))+30, #StartDate)
SET #StartDate = DateAdd(ss,- (DatePart(ss,#StartDate)), #StartDate)
SET #StartDate = DateAdd(ms,- (DatePart(ms,#StartDate)), #StartDate)
Hope this helps someone.

How do I compare against the current week using SQL Server?

How do I compare an SQL Server date column against the current week?
For instance:
WHERE [Order].SubmittedDate = *THIS WEEK*
You could convert your date to a week number and compare this to the week number from the current date. Likewise, you'll need to compare the year as well, so that you don't get last year's weeks.
WHERE DATEPART(wk, [Order].SubmittedDate) = DATEPART(wk, GETDATE())
AND DATEPART(yy, [Order].SubmittedDate) = DATEPART(yy, GETDATE())
Assuming you are meaning always "this week" and there are no records with Submitted dates in the future, which I imagine could be the case you can do:
WHERE [Order].SubmittedDate >= DATEADD(dd, -(DATEPART(dw, GETDATE()) -1), GETDATE())
If dates do go into the future, the full restriction to this week is:
WHERE [Order].SubmittedDate >= DATEADD(dd, -(DATEPART(dw, GETDATE()) -1), GETDATE())
AND [Order].SubmittedDate < CAST(CONVERT(VARCHAR(10), DATEADD(dd, (8 - DATEPART(dw, GETDATE())), GETDATE()), 120) AS DATETIME)
I'd strongly recommend using a clause based on a start and end date like this, as it will allow efficient index use so should perform better.
Try this:
WHERE [Order].SubmittedDate BETWEEN
DATEADD(d, - DATEPART(dw, GETDATE()) + 1, GETDATE()) AND
DATEADD(d, 7 - DATEPART(dw, GETDATE()) , GETDATE())
Maybe this can run faster, as doesn't needs to be evaluated everytime:
DECLARE #StartDate DATETIME,
#EndDate DATETIME
SELECT #StartDate = DATEADD(d, - DATEPART(dw, GETDATE()) + 1, GETDATE()),
#EndDate = DATEADD(d, 8 - DATEPART(dw, GETDATE()) , GETDATE())
-- // Strip time part, so week starts on Sunday 00:00
SELECT #StartDate = CAST(FLOOR(CAST(#StartDate AS FLOAT)) AS DATETIME),
#EndDate = CAST(FLOOR(CAST(#EndDate AS FLOAT)) AS DATETIME)
...
WHERE [Order].SubmittedDate >= #StartDate AND [Order].SubmittedDate < #EndDate