SQL fetch data for the present year until previous week friday - sql

Am trying to fetch data in SQL until previous week Friday for the present year from the datetime field fetchDate
I tried something like this but it fetches until today
(year(fetchDate) = year(GETDATE()) and month(fetchDate) <= month(GETDATE()) and day(fetchDate) <= day(GETDATE()))
whereas
(year(fetchDate) = year(GETDATE()) and month(fetchDate) <= month(GETDATE()) and day(fetchDate) <= day(DATEADD(wk,DATEDIFF(wk,7,GETDATE()),4)))
brings me data only for the present month of the year until last week.

I believe what you need is the following:
WHERE YEAR(fetchDate) = YEAR(CURDATE())
AND fetchDate < DATE_SUB(NOW(), INTERVAL ((7 + WEEKDAY(DATE_SUB(NOW(), INTERVAL 1 WEEK)) - 4) % 7) DAY)
We get how many days ago last week's Friday was with:
((7 + WEEKDAY(DATE_SUB(NOW(), INTERVAL 1 WEEK)) - 4) % 7)

I would rather go for the following solution as it is sargable. Inside the WHERE predicate we are not wrapping the fetchdate into a function (e.g. YEAR(Fetchdate)), the query optimizer could use existing indexes and does not have to scan the whole table. Especially for BI workloads where this query is common, it is extremely important to optimize for that a lot of records are queried. It comes at the cost of little less readability
declare #tab table
(
fetchdate datetime
)
insert into #tab
values ('2019-01-01'),('2019-03-15'),('2018-12-31'),('2019-03-16')
SELECT
*,
case when datepart(weekday, getdate()) >5 then
DATEADD(DAY, +4, DATEADD(WEEK, DATEDIFF(WEEK, 0, getdate()), 0))
else DATEADD(DAY, -3, DATEADD(WEEK, DATEDIFF(WEEK, 0, getdate()), 0)) end as TestLastFriday,
DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0) as TestFirstDayOfYear
FROM #tab
where
fetchdate <= case when datepart(weekday, getdate()) >5 then DATEADD(DAY, +4, DATEADD(WEEK, DATEDIFF(WEEK, 0, getdate()), 0))
else DATEADD(DAY, -3, DATEADD(WEEK, DATEDIFF(WEEK, 0, getdate()), 0)) end and
fetchdate >= DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0)

Related

Get last date of the previous month Transact-SQL

I am trying to fetch data for the previous full month, but the data from the last day is not fetching.
Output: Previous Month is April and this condition only retrieving data up to 29th April. Data for 30th April is missing.
Can please someone help me to correct this.
OLH.DateStamp > CONVERT(VARCHAR,DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())-1, 0),101)
And
OLH.DateStamp < CONVERT(VARCHAR,DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE())-1, -1),101))
Thanks in advance
The simplest way to get data for the previous month is:
DATEDIFF(month, OLH.DateStamp, GETDATE()) = 1
However, that does not use indexes. So, a better method is:
OLH.DateStamp >= DATEADD(MONTH, -1, DATEADD(DAY, 1 - DAY(GETDATE()), CAST(GETDATE() as DATE))) AND
OLH.DateStamp < DATEADD(DAY, 1 - DAY(GETDATE()), CAST(GETDATE() as DATE))
The expression:
DATEADD(DAY, 1 - DAY(GETDATE), CAST(GETDATE() as DATE))
returns midnight on the first day of the current month.
You should try last day of Month Should be <= OLH.Datestamp
To get Desired Output you are Looking for:
--Use It In Where Clause
DECLARE #FirstDayOfLastMonth
DATETIME = CONVERT(DATE, DATEADD(d, -( DAY(DATEADD(m, -1, GETDATE() -
2)) ), DATEADD(m, -1, GETDATE() - 1)))
,#LastDayOfLastMonth DATETIME = CONVERT(DATE, DATEADD(d, -( DAY(GETDATE()) ), GETDATE()))
OLH.DateStamp >= CONVERT(VARCHAR, #FirstDayOfLastMonth , 101) AND
OLH.DateStamp <= CONVERT(VARCHAR, #LastDayOfLastMonth , 101)

SQL - pick current date from machine and compare

For the below query
Scenario 1: Current Year (Previous Week) - For eg- Week 31
sum(case when s.Date between '2016-07-17' and '2016-07-23' then s.SELLINC else 0 end) ActualSales
Scenario 2: Last Year (Previous Week) - For eg- Week 31
sum(case when s.Date between '2015-07-19' and '2015-07-25' then s.SELLINC else 0 end) LastYrVarianc
Scenario 3: Picking dates between beginning of current year till today's date
sum(case when s.Date between '2016-01-01' and '2016-09-05' then s.SELLINC else 0 end) YrToDateActual
Scenario 4: Picking dates between beginning of last year till last year today's date
sum(case when s.Date between '2015-01-01' AND '2015-09-05' then s.SELLINC else 0 end) LastYrToDateActual
Instead of hard coding the date. I would like to pick current date from machine and compare.
Week start from Sunday and ends Saturday. Any help please?
First off, GETDATE() is the SQL Server function for today's date
DATEADD(..) is the function to add stuff to dates
1) case when s.date between DATEADD(dd,-6,getdate()) and getdate()) then...
2) case when s.date between DATEADD(yy,-1,DATEADD(dd,-6,getdate())) and DATEADD(yy,-1,getdate()) then ...
3) case when s.date between DATEADD(yy, DATEDIFF(yy,0,getdate()), 0) and getdate() then ...
4) case when s.date between dateadd(yy,-1,DATEADD(yy, DATEDIFF(yy,0,getdate()), 0)) and DATEADD(yy,-1,GETDATE()) then ..
A little help from here
I assume that your week starts from sunday to saturday.
You can use this query,
Scenario-1 (PreviousWeekStartDate and PreviousWeekEndDate)
s.Date between convert(date,dateadd(wk, datediff(wk, 0, getdate()) - 1, 0) - 1) and convert(date,dateadd(wk, datediff(wk, 0, getdate()) - 1, 0) + 5)
Scenario-2 (LastYearPreviousWeekStartDate and LastYearPreviousWeekEndDate)
s.Date between convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) - 1) and convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) + 5)
Scenario-3 (StartOfYear and CurrentDate)
s.Date between convert(date,DATEADD(yy, DATEDIFF(yy, 0, getdate()), 0)) and convert(date,getdate())
Scenario-4 (StartOfLastYear and CurrentDateLastYear)
s.Date between convert(date,DATEADD(yy, DATEDIFF(yy, 0, dateadd(YEAR, - 1, getdate())), 0)) and convert(date,dateadd(YEAR, - 1, getdate()))
Use date arithmetic
declare #weekNo int = 31;
--start of the year
declare #ys datetime = dateadd(year,datediff(year,0,getdate()),0)
-- start of the first week of the year (may start in December of prev year)
declare #y1ws datetime = dateadd(week,datediff(week,0,#ys),0)
select #ys, #y1ws, dateadd(week, #weekNo-1, #y1ws) [week31 start], dateadd(week, #weekNo, #y1ws) [week32 start]
-- use it this way for week 31
-- .. where somedate >= [week31 start] and somedate < [week32 start]
SELECT
GETDATE(), -- Today
DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0), -- Start of this year
DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()) - 1, 0), -- Start of last year
DATEADD(WEEK, DATEDIFF(WEEK, 0, GETDATE()), 0), -- Start of this week
DATEADD(WEEK, DATEDIFF(WEEK, 0, GETDATE()) - 1, 0) -- Start of last week
I think using DATEPART (Transact-SQL) is a more portable solution. My answers for scenario 1 and scenario 2 refer a natural week starting from Sunday, which are different from JohnHC's answers (referring last 7 days).
--
-- Scenario 1: Current Year (Previous Week) - For eg- Week 31
--
CASE WHEN
DATEPART(ww, s.Date) = DATEPART(ww, GETDATE()) - 1 AND
DATEPART(yy, s.Date) = DATEPART(yy, GETDATE())
THEN ...
--
-- Scenario 2: Last Year (Previous Week) - For eg- Week 31
--
CASE WHEN
DATEPART(ww, s.Date) = DATEPART(ww, GETDATE()) - 1 AND
DATEPART(yy, s.Date) = DATEPART(yy, GETDATE()) - 1
THEN ...
--
-- Scenario 3: Picking dates between beginning of current year till today's date
--
CASE WHEN
DATEPART(yy, s.Date) = DATEPART(yy, GETDATE())
THEN ...
--
-- Scenario 4: Picking dates between beginning of last year till last year today's date
--
CASE WHEN
DATEPART(yy, s.Date) >= DATEPART(yy, GETDATE()) - 1
THEN ...

First business day of the current month - SQL Server

How could I get the first business day of the current month?
Without create a function, only select.
something like that:
SELECT CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(GETDATE())-1), GETDATE()), 101)
somebody knows please?
Thanks.
A Simple case statement could do it
SELECT CASE
WHEN DATENAME(WEEKDAY, dateadd(mm, DATEDIFF(MM, 0, getdate()), 0)) = 'Saturday'
THEN dateadd(mm, DATEDIFF(MM, 0, getdate()), 0) + 2
WHEN DATENAME(WEEKDAY, dateadd(mm, DATEDIFF(MM, 0, getdate()), 0)) = 'Sunday'
THEN dateadd(mm, DATEDIFF(MM, 0, getdate()), 0) + 1
ELSE dateadd(mm, DATEDIFF(MM, 0, getdate()), 0)
END
This will literally give you what you're asking for -- the first business day in a month if we define a business day as "any day that's not a Saturday or a Sunday". But this is is a very narrow definition of "business day" that is not appropriate when taking into account holidays and cultural differences, so it generalizes poorly. The typical solution for this problem is to create a table that actually holds the working days (which is generated somewhere just before he year, or calculated in advance if that's feasible), and simply look it up in that.
SELECT DATEADD(DAY,
CASE
(DATEPART(WEEKDAY, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0)) + ##DATEFIRST - 1) % 7
WHEN 6 THEN 2
WHEN 7 THEN 1
ELSE 0
END,
DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0)
)
This solution uses ##DATEFIRST to avoid any language issues -- using DATEPART(WEEKDAY, ...) on its own or DATENAME() only works if we assume a specific region.
If you have more flexibility in your SELECT statement, you might be able to use something like this:
;With Daterange As
(
Select DateAdd(Month, DateDiff(Month, 0, GetDate()), 0) As Date Union All
Select DateAdd(Day, 1, Date) As Date
From DateRange
Where Date < DateAdd(Day, 6, DateAdd(Month, DateDiff(Month, 0, GetDate()), 0))
)
Select Convert(Date, Min(Date)) FirstBusinessDay
From Daterange
Where DatePart(WeekDay, Date) Not In (7, 1)
Try this.
SELECT CASE
WHEN Datename(dw, Dateadd(dd, -Datepart(dd, Getdate()) + 1, Getdate())) = 'Saturday' THEN Dateadd(dd, -Datepart(dd, Getdate()) + 3, Getdate())
WHEN Datename(dw, Dateadd(dd, -Datepart(dd, Getdate()) + 1, Getdate())) = 'Sunday' THEN Dateadd(dd, -Datepart(dd, Getdate()) + 2, Getdate())
ELSE Dateadd(dd, -Datepart(dd, Getdate()) + 1, Getdate())
END
Explanation :
Find the first day of the month.
Dateadd(dd, -Datepart(dd, Getdate()) + 1, Getdate())
Then check the day of the previous date by using Datename function.
Datename(dw, Dateadd(dd, -Datepart(dd, Getdate()) + 1, Getdate()))
If the Datename is Saturday the add 2 days to the first day of the month . if it is sunday then add 1 day to the first day of the month else get the first day of the month

SQL - Get data based on months form a dateTime column

With SQL Server, I have a column with a launch date (dateTime). I want to report on everything that is being launched between all of last month (from viewing date) thru all of this month and next month.
So basically a full 3 month period.
What is the best way to write that?
Are you looking for something like this?
DECLARE
#StartDate DATETIME,
#EndDate DATETIME
SELECT
#StartDate = DATEADD(MM, DATEDIFF(MM, 0, GETDATE()) - 1, 0),
#EndDate = DATEADD(MM, DATEDIFF(MM, 0, GETDATE()) + 2, 0)
-- DATEADD(MM, DATEDIFF(MM, 0, GETDATE()), 0), -- beginning of this month
-- DATEADD(MM, DATEDIFF(MM, 0, GETDATE()) - 1, 0), -- beginning of last month
-- DATEADD(MM, DATEDIFF(MM, 0, GETDATE()) + 1, 0) -- beginning of next month
-- DATEADD(MM, DATEDIFF(MM, 0, GETDATE()) + 2, 0) -- beginning of two months from now
SELECT
*
FROM
[Table]
WHERE
[LaunchDate] >= #StartDate
AND [LaunchDate] < #EndDate
This will give you all the results starting from the beginning of the previous month and before the beginning of two months from now (a full 3 month range)
Maybe something like SELECT /*what_you_want*/ from launches WHERE lauchDate BETWEEN DATEADD(MONTH, DATEDIFF(MONTH, '19000101', GETDATE()) - 1, '19000101') AND DATEADD(MONTH, DATEDIFF(MONTH, '19000101', GETDATE()) + 2, '19000101')
SELECT Foo
FROM Bar
WHERE LaunchDate >= DATEADD(mm, -1, GETDATE())
AND LaunchDate <= DATEADD(mm, 1, GETDATE())

GETDATE last month

I am trying to list last a website's statistics.
I listed Last 30 days with;
CONVERT(VARCHAR(10), S.DATEENTERED, 101)
BETWEEN
CONVERT(VARCHAR(10), GETDATE()-30, 101)
AND
CONVERT(VARCHAR(10), GETDATE(), 101)
and this month with;
RIGHT(CONVERT(VARCHAR(10), S.DATEENTERED, 103), 7) =
RIGHT(CONVERT(VARCHAR(10), GETDATE(), 103), 7)
but I have no idea what query to use for last month. I tried with;
RIGHT(CONVERT(VARCHAR(10), S.DATEENTERED, 103), 7) =
RIGHT(CONVERT(VARCHAR(10), GETDATE()-1, 103), 7)
Did not work.
Dates are always a joy to work with in any programming language, SQL not excluded.
To answer your question to find all records that occurred last month
select S.DATEENTERED
,*
from sometable S
where S.DATEENTERED
between dateadd(mm, datediff(mm, 0, dateadd(MM, -1, getdate())), 0)
and dateadd(ms, -3, dateadd(mm, datediff(mm, 0, dateadd(MM, -1, getdate())) + 1, 0))
order by 1
To expand the best means for getting records within a certain time-frame is by utilizing the datediff function, dateadd function, and the between condition in the where clause.
select 'howdy'
,getdate()
where getdate()
between dateadd(mm, 0, 0)
and dateadd(ms, -3, dateadd(mm, datediff(mm, 0, dateadd(mm,-1,getutcdate())) + 1, 0))
The above code will result in no records returned because it is checking to see if today's date is between 1900-01-01 00:00:00.000 and the last possible recorded date of last month (the last day and 23:59:59.997 - SQL Server DATETIME columns have at most a 3 millisecond resolution).
The following code will return a record as the date we are searching for is one month ago.
select 'howdy'
,dateadd(mm, -1, getdate())
where dateadd(mm, -1, getdate())
between dateadd(mm, 0, 0)
and dateadd(ms, -3, dateadd(mm, datediff(mm, 0, dateadd(mm,-1,getutcdate())) + 1, 0))
A break down of the where clause:
WHERE getdate() -- date to check
between dateadd(mm, 0, 0) -- begin date
and dateadd(ms, -3, dateadd(mm, datediff(mm, 0, dateadd(mm,-1,getutcdate())) + 1, 0)) -- end date
Finally, a variety of dates can be ascertained in this manner here is a pretty complete list:
select dateadd(mm, 0, 0) as BeginningOfTime
,dateadd(dd, datediff(dd, 0, getdate()), 0) as Today
,dateadd(wk, datediff(wk, 0, getdate()), 0) as ThisWeekStart
,dateadd(mm, datediff(mm, 0, getdate()), 0) as ThisMonthStart
,dateadd(qq, datediff(qq, 0, getdate()), 0) as ThisQuarterStart
,dateadd(yy, datediff(yy, 0, getdate()), 0) as ThisYearStart
,dateadd(dd, datediff(dd, 0, getdate()) + 1, 0) as Tomorrow
,dateadd(wk, datediff(wk, 0, getdate()) + 1, 0) as NextWeekStart
,dateadd(mm, datediff(mm, 0, getdate()) + 1, 0) as NextMonthStart
,dateadd(qq, datediff(qq, 0, getdate()) + 1, 0) as NextQuarterStart
,dateadd(yy, datediff(yy, 0, getdate()) + 1, 0) as NextYearStart
,dateadd(ms, -3, dateadd(dd, datediff(dd, 0, getdate()) + 1, 0)) as TodayEnd
,dateadd(ms, -3, dateadd(wk, datediff(wk, 0, getdate()) + 1, 0)) as ThisWeekEnd
,dateadd(ms, -3, dateadd(mm, datediff(mm, 0, getdate()) + 1, 0)) as ThisMonthEnd
,dateadd(ms, -3, dateadd(qq, datediff(qq, 0, getdate()) + 1, 0)) as ThisQuarterEnd
,dateadd(ms, -3, dateadd(yy, datediff(yy, 0, getdate()) + 1, 0)) as ThisYearEnd
Using the above list a range of any type can be determined.
The following will find you the start of the last month:
-- Start of last month
SELECT CAST('01 '+ RIGHT(CONVERT(CHAR(11),DATEADD(MONTH,-1,GETDATE()),113),8) AS datetime)
You would then find the start of this month, using the following, minus one.
-- Start of the month
SELECT CAST('01 '+ RIGHT(CONVERT(CHAR(11),GETDATE(),113),8) AS datetime)
When I have to work with dates in SQL Server I often reference Robyn Page's SQL Server DATE/TIME Workbench. The workbench (tutorial) is well laid out and contains just about everything I have ever needed when working with dates on SQL Server.
How about this?
select DATEADD(month, -1, GETDATE())
I would suggest using the first day of last month and the first day of the current month for the operation and rather than using BETWEEN use >= and <. That's my personal opinion, but I believe you will find there are performance and maintainability benefits to this approach.
Here's the sql. You will notice I've included the last day of the last month value just in case you end up going with another approach.
Keep in mind, these dates are based off of 12:00AM that day. In other words, getting values between 6/1/2009 and 6/30/2009 won't get you what you want as all of 6/30/2009 is excluded. If you use the first day of July (7/1/2009) you are covered.
Again, I recommend avoiding BETWEEN all together as shown below. Best of luck.
Declare #LastMonthFirstDay datetime
Declare #LastMonthLastDay datetime
Declare #ThisMonthFirstDay datetime
Set #LastMonthFirstDay = DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP) - 1, 0);
Set #ThisMonthFirstDay = DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP), 0);
Set #LastMonthLastDay = DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP), 0));
Select * From Table
Where DateEntered >= #LastMonthFirstDay
And DateEntered < #ThisMonthFirstDay;
Try using the DATEADD function. You can add a -1 with the MONTH (mm) datepart and it should work. Here is a link
where year(S.DATEENTERED) = year(dateadd(mm, -1, getdate())) and month(S.DATEENTERED) = month(dateadd(mm, -1, getdate()))
Might not be good performance-wise but you've got the idea.
GET FIRST DAY OF LAST MONTH
SELECT DATEADD(MM, DATEDIFF(MM, '01/01/2000', DATEADD(MM, -1,GETDATE())), '01/01/2000')
GET LAST DAY OF LAST MONTH
SELECT DATEADD(SS,-1,DATEADD(MM, DATEDIFF(MM,'01/01/2000',GETDATE()),'01/01/2000'))
Then search based on this range.
Try:
declare #lastm int
set #lastm = datepart(mm,getdate()) - 1
...
where datepart(mm,s.dateentered) = #lastm