sql date parameter in query - sql

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

Related

How to account for 31 days using SQL

I am trying to generate rolling data for month. However, I am having an issue where the query doesnt generate any data when the month has 31 days.
I am defining my days here:
declare #today datetime
set #today = getdate()
declare #enddate datetime
set #enddate = #today
declare #begindate datetime
set #begindate = dateadd(mm, datediff(m,0,#today),0)
Then I am calling the days in my query using:
PURCHDATE BETWEEN #begindate AND #enddate
I can see my issue where my begin date is first day of the month and end date is today. How can I make this work for 31 day months?
You could do this
WHERE YEAR(PURCHDATE) = YEAR(GETDATE()) AND MONTH(PURCHDATE) = MONTH(GETDATE())
I would recommend:
PURCHDATE >= CONVERT(date, DATEADD(day, 1 - day(getdate()), getdate())) AND
PURCHDATE < CONVERT(date, DATEADD(day, 1, EOMONTH(getdate())))

Update time portion of a datetime in SQL Server

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)

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())

How to run a query for "Today's" date from 12:00am to 11:59PM

I have a simple query that pulls a payout report for our day. I'd like to automate this to send every night, however I want the report to run for That day 12:00AM - 11:59 PM daily... I will be sending the reports at 9:00 PM, so I suppose it will only need to get until 9:00 PM if that's easier.
Here is my query:
SELECT COUNT(*) AS Number, SUM(dblPayoutAmt) AS Amount
FROM Payouts
WHERE (dtCreated BETWEEN #startdate AND #enddate)
Don't use BETWEEN, use >= the start date and < a day past the end date:
WHERE (dtCreated >= #startdate AND dtCreated < DATEADD(day, 1, #enddate))
The reason is that BETWEEN will find up until 12:00am of the end date, but not past then.
UPDATED
For todays date, you can do this:
WHERE DATEADD(dd, 0, DATEDIFF(dd, 0, dtCreated)) = DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))
This will check that it has a dtCreated equal to some point today.
UPDATED
As #ScottChapman has pointed out, you can do the same thing without the conversion gymnastics by casting to the DATE type directly. This type is only available in MSSQL 2008 and later, however.
SET #StartDate = CAST(GETDATE() AS date)
SET #EndDate = DATEADD(MINUTE, -1, DATEADD(DAY, 1, #StartDate))
SELECT COUNT(*) AS Number, SUM(dblPayoutAmt) AS Amount
FROM Payouts
WHERE (dtCreated BETWEEN #startdate AND #enddate)
Some of these answers are close, but exclude times in the final minute of the day, like 11:59:30 PM. This query will include all of today:
SELECT COUNT(*) AS Number, SUM(dblPayoutAmt) AS Amount
FROM Payouts
WHERE (dtCreated >= CAST(GETDATE() as date) AND dtCreated < DATEADD(day, 1, CAST(GETDATE() as date)))
Note that this won't work in SQL Server 2005 or below, as the date type was added in SQL Server 2008.
As you're using SQL/Server 2008 you can remove any time element from a DATETIME column by converting it to DATE and select on that, E.g.
SELECT COUNT(*) AS Number, SUM(dblPayoutAmt) AS Amount
FROM Payouts
WHERE CONVERT(DATE,dtCreated) = CONVERT(DATE,GETDATE())
Very much more elegant
[EDIT]
Oh, I've just read Scott Chapman's answer, it's better because if dtCreated is indexed then the query will be more efficient.
Preceding answers also include data < 12.00 am
SELECT
COUNT(*) AS Number
, SUM(dblPayoutAmt) AS Amount
FROM
Payouts
WHERE
dtCreated >= dateadd( hour, 12, cast( cast( getdate() as date ) as datetime ))
and dtCreated < dateadd( second, -1, dateadd(day, datediff(day, -1, getdate()), 0))
set them both to SIMPLE date example: BETWEEN '2012-12-19' AND '2012-12-20' with no timestamp on them, then select the between.
In this example if you set the date for end to '2012-12-20 23:59:59.999' and then do a SELECT #enddate it returns '2012-12-21 00:00:00.000'
OR to use a function type syntax:
declare #mystart as datetime
declare #myend as datetime
set #mystart = dateadd(day,datediff(day,0,CURRENT_TIMESTAMP),0)
set #myend = dateadd(day,datediff(day,0,CURRENT_TIMESTAMP),1)
select #mystart, #myend
the #mystart here is set to ONLY the date part (time is 00:00:00.000) and the end is sent to that plus one day, so the BETWEEN syntax works.

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.