How to account for 31 days using SQL - 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())))

Related

Setting SQL variables for First day of month and 1 year before

Possibly a dumb question because I'm totally new to SQL (I mean never touched it before today 😟) but I'm adjusting a report in a program we use, so it always gets values for the year ending last month (we run it at the beginning of every month).
So, I want #EndDate to be either 12:59pm of the end of last month, or 00:00am of first of this month, and I want #BeginDate to be same minus 1 year. My code is getting a 'syntax error near keyword SET' - I barely even know what this means, and the past hour on google hasn't helped.
Code:
DECLARE #BeginDate DateTime;
DECLARE #EndDate DateTime;
SET #EndDate = CONVERT(Datetime, CONVERT(date, DATEFROMPARTS(YEAR(GetDate()), MONTH(GetDate()),1)), -- Beginning of this month at 00:00 AM
SET #BeginDate = DATEADD(yy, -1, #EndDate) -- a year before the End date
This is all I've added to the existing report, so if it doesn't work completely independently it won't work at all. Over to you guys ... any suggestions? I'm guessing it's a simple, dumb mistake?
You could try formating it to datetime
DECLARE #EndDate DateTime, #BeginDate DateTime;
SET #EndDate = FORMAT(GetDate(), 'yyyy-MM-01 00:00:00.000')
SET #BeginDate = DATEADD(yy, -1, #EndDate)
Can you try the following. You are trying to set '#enddate' without initially declaring:
DECLARE #EndDate DateTime,#BeginDate DateTime;
select #EndDate = convert(datetime,datefromparts(year(getdate()),month(getdate()),1))
select #BeginDate = DATEADD(yy, -1, #EndDate)
select #EndDate,#BeginDate

Having issues with dates in SQL

I'm writing a report that needs to collect data each day, between 0900hs and 1700hs.
I thought it would be fine as follows:
cast(convert(char(8),t.trxtime,112)as time)
between CONVERT(VARCHAR(5),getdate(),108) >= '09:00'
and CONVERT(VARCHAR(5),getdate(),108) < '17:00'
....BUT no cigar.
Thank you!!!
Hmmm, you could just use datepart():
where datepart(hour, t.trxtime) between 9 and 16 and
cast(t.trxtime as date) = cast(getdate() as date)
I'm not sure if the date comparison is actually necessary.
You could do something like this (assuming you mean actually for the current date, and not for every date in a range:
declare #startDate datetime
declare #endDate datetime
select #startDate = '2014-11-03 09:00:00',
#endDate = '2014-11-03 17:00:00'
select *
from table
where myDate between #startDate and #endDate
if you did mean between 0900 and 1700 for each day, you could do:
declare #startDate datetime
declare #endDate datetime
select #startDate = '2014-10-03',
#endDate = '2014-11-03' -- note i'm still limiting it to a range of ~1 month
select *
from table
where myDate between #startDate and #endDate
and datepart(hour, myDate) between 9 and 17

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.

SQL 1st of the month to the end of the month

I have an #StartDate and #EndDate.
I need the #StartDate to be the day the query is ran(which will always be the first of the month) and the #EndDate to be exaclty at the end of the month no matter if the month is 30 or 31 days, etc.
A worked example:
DECLARE #StartDate DATETIME, #EndDate DATETIME
SET #StartDate = '2010-01-01 00:00:00.000'
SET #EndDate = DATEADD(m, 1, #StartDate)
SELECT #StartDate, #EndDate - 1
Basically you want to take the start date, add one month (that's what the DATEADD is doing), and then deduct one day.
The output from that query is:
StartOfMonth EndOfMonth
----------------------- -----------------------
2010-01-01 00:00:00.000 2010-01-31 00:00:00.000