I'm currently working on a query that returns records from within a date range. The ideal is for the start date to be everything from 2015 onward. In theory, shouldn't each of the three SET statements below set the variable to 2015*?
DECLARE #startDate datetime;
SET #startDate = '20150101';
SET #startDate = YEAR(GETDATE());
SET #startDate = DATEPART(yyyy,GETDATE());
Only the first one, the hardcoded date, behaves as expected. The other two return ALL records that are being queried through. Am I missing something here?
*EDIT: I apologize for how unclear I was with that initially. Basically, #startDate should be set to 01-01-XXXX, where XXXX is whatever year today's date is a part of. It's being compared against another DATETIME variable. I hope that clarifies things.
The answer to your question is "No". The variable #StartDate is date time. This doesn't make sense:
set #startDate = 2015
It doesn't make sense. An integer that looks like a year is not a date.
If you want the first day of the year, you can do:
set #startDate = dateadd(day,
1 - datepart(dayofyear, getdate()),
cast(getdate() as date)
) as FirstDayOfYear
I think this would work (for SQL-Server):
SET #startDate = cast(YEAR(GETDATE()) as varchar(4))
SET #startDate = cast(DATEPART(yyyy,GETDATE()) as varchar(4))
This will show you what's happening:
DECLARE #startDate datetime
SET #startDate = '20150101'
select #startdate
SET #startDate = YEAR(GETDATE())
select #startdate
SET #startDate = cast(YEAR(GETDATE()) as varchar(4))
select #startdate
SET #startDate = DATEPART(yyyy,GETDATE())
select #startdate
SET #startDate = cast(DATEPART(yyyy,GETDATE()) as varchar(4))
select #startdate
YEAR(GETDATE()) and DATEPART(yyyy,GETDATE()); will return just the year part of the date, so if you ran them today you would get 2015 back, not the date 2015-01-01 as you seem to want.
If you want to force the date value to the beginning of the current year, one way would be:
SET #startDate = YEAR(GETDATE()) + '-01-01';
Related
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
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())))
I have the following two dates :
startDate = '2017-04-04' and endDate = '2017-04-12'
I would like to find the total count of days between these two dates excluding 'Fridays' using SQL Server.
Any Help from the SQL Server Experts will be highly appreciated!! Thanks in Advance!!
You can use DATENAME to check for 'Friday' do this, something like this :
DECLARE #startDate DATETIME
DECLARE #endDate DATETIME
SET #startDate = '2017-04-04'
SET #endDate = '2017-04-12'
Declare #count int
set #count=0
while #startDate < #endDate
Begin
IF DATENAME(dw, #startDate) <> 'Friday'
SET #count = #count + 1
SET #startDate = DateAdd(d, 1, #startDate)
END
select #count
This will result in :
7
just add below clause to your query
select count(*) from table
where startDate >= '2017-01-12' and endDate <= '2017-04-27'
and datename(WEEKDAY,startdate))<>'Friday'
i show you my logic is getting error only when month is December
declare #startDate datetime
declare #endDate datetime
set #startDate = convert(varchar(2),#month)+'/1/'+ convert(varchar(4),#year)
set #endDate = dateadd(DD,-1,(convert(varchar(2),#month+1)+'/1/'+convert(varchar(4),#year)))
while(#startDate < #endDate+1)
begin
insert into #tempday
select #startDate
set #startDate = dateadd(day, 1, #startDate )
end
please help
Once you have #startdate, use:
set #enddate = dateadd(day,-1,dateadd(month,1,#startdate))
And I don't think you mean plsql...
There are other things you could think about too, such as not using a while-loop. Why not query a table that has plenty of rows (such as sys.all_columns) and use:
insert #tempday
select top (datediff(day,#startdate,#enddate)+1)
dateadd(day,row_number() over (order by (select 1))-1,#startdate)
from sys.all_columns;
In case of December #month+1 will get you 13 which is not a valid month number
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.