Click here to Skip to main content
15,887,135 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
My activity is to generate report from a table for yesterday data. If today is Monday I have to generate report for Saturday and Sunday. If today is third week Monday I have to generate report for Friday, Saturday & Sunday.

What I have tried:

--Yesterday
select convert(varchar(8),GETDATE()-1,112)
Posted
Updated 19-Jun-18 0:51am
Comments
CHill60 15-Jun-18 7:34am    
There is no need to convert the date - use DatePart if you want the day name
kirthiga S 15-Jun-18 7:37am    
My requirement is how to specify the conditions for monday of third week and other weeks
CHill60 15-Jun-18 7:40am    
3rd week of what? The year? the month?
kirthiga S 15-Jun-18 7:41am    
the month
Richard MacCutchan 15-Jun-18 7:38am    
Check what day is today, and what week it is, and adjust your request accordingly.

I created the following test data to demonstrate what you need to do - it's just a series of dates with a number to represent some data
SQL
create table #test
(
	datadate date,
	data int
)
declare @startdate date = '2018-05-01'
declare @enddate date = getdate()


;WITH q AS
    (
    SELECT  @startdate AS d1, 1 as d2
    UNION ALL
    SELECT  dateadd(d, 1, d1) , d2 + 1 
    FROM    q
    WHERE dateadd(d, 1, d1) < @enddate
    )
INSERT INTO #test
SELECT  d1, d2
FROM    q
To get "yesterday's" data is simple:
SQL
SELECT * FROM #test
WHERE datadate = DATEADD(d, -1, cast(getdate() as date))
The CAST is just to get rid of the time element of getdate() otherwise no data is returned.

To get the week number I'm using the built in DATEPART function with a parameter of week. E.g.
SQL
select * FROM #test
WHERE (DATEPART(week,datadate)- DATEPART(week,DATEADD(m, DATEDIFF(m, 0, datadate), 0))) + 1 = 3


To determine what day of the week it is I'm not going to use the word "Monday" etc as that is language dependent. I'm going to use the index or number of the day within the week. But this depends on your setting of @@DATEFIRSTLukeH at this post[^] provides a nice solution:
SQL
select *, DATENAME(dw, datadate), DATEPART(dw, datadate) FROM #test 
WHERE ((DATEPART(dw, datadate) + @@DATEFIRST) % 7) NOT IN (0, 1)
Now you need to put it all together. You could use CASE in the WHERE clause, but I'm not a fan. In my example below I use a CTE (Common Table Expression) to first work out how many days back I want to include and then use BETWEEN in a simple WHERE clause. You should substitute getdate() for @testdate in the code below:
SQL
declare @testdate date = '2018-06-12' -- '2018-05-7' -- Monday -- monday of 3rd week '2018-06-11' -- tuesday '2018-06-12'
;with q1 as 
(
	select datadate, data
	,daysback = CASE WHEN ((DATEPART(dw, @testdate) + @@DATEFIRST) % 7) = 2 AND (DATEPART(week,@testdate)- DATEPART(week,DATEADD(m, DATEDIFF(m, 0, @testdate), 0))) + 1 = 3 THEN
		-- Monday of 3rd week  so we want Fri, Sat, Sun ... this date minus 3 days
		-3
	WHEN ((DATEPART(dw, @testdate) + @@DATEFIRST) % 7) = 2  THEN
		-- any other monday so we want Sat and Sun
		-2
	ELSE
		-- any other day so just yesterday
		-1 
	END 
	from #test
)
SELECT *
from q1
WHERE datadate BETWEEN dateadd(d, daysback, @testdate) AND dateadd(d, -1, @testdate)

[Edit after OP comment]
(Anyone thinking that the 3rd Monday of the month is the same as the Monday of the 3rd week are the same needs to consider how you define the first week of a month - is it the first whole week starting on a specific day - usually Sunday or Monday, or is it the 1st to 7th of a month regardless of day)

To have the 3rd Monday of the month, rather than the Monday of the 3rd week then use this in the CASE
SQL
WHEN ((DATEPART(dw, @testdate) + @@DATEFIRST) % 7) = 2 AND  ceiling(DAY(@testdate) / 7.0) = 3 THEN
		-3
Explanation: We discussed that
SQL
((DATEPART(dw, @testdate) + @@DATEFIRST) % 7) = 2
will find "Mondays". The extra bit can be explained by breaking it down:
DAY(@testdate)
is going to return the day of the month, e.g. today 18 for 18-Jun-2018. Dividing that by the number of days in a week gives you an indication of which week it is in. For example 18 / 7.0 gives 2.571428. Note the 7.0, otherwise 18/7 gives the answer 2. You could interpret that 2.571428 as "we've already had 2 whole Mondays this month and now we're part way into the next one". So by adding ceiling we can determine that "the next one" is actually the 3rd Monday (for this month).
Ok, that's probably not the best explanation but hopefully you can see what is happening.

As an aside (and a credit), this was adapted from a post by Lynn Pettis who has lots of handy stuff on her blog SQL Musings from the Desert[^] at SQL Server Central.
 
Share this answer
 
v2
Comments
kirthiga S 18-Jun-18 5:51am    
Query is working. Instead of monday of 3rd week I need 3rd monday of the month
CHill60 18-Jun-18 8:19am    
I've updated my solution
CHill60 19-Aug-19 5:04am    
The link in my solution is now broken. Replacement is Some Common Date Routines – SQLServerCentral[^]
(Not editing solution as it will resurrect this post)
Thank you all. Finally I got my solution.

Declare @StartDate datetime,@EndDate datetime
set @EndDate=GetDate()-1 

select case when ((datepart(D,@EndDate-1)-1)/7+1) not in (2) and (datename(dw,@EndDate-1))='Saturday' then @EndDate-1 
			when ((datepart(D,@EndDate-1)-1)/7+1) in (2) and (datename(dw,@EndDate-1))='Saturday' then @EndDate-2 Else @EndDate End StartD,@EndDate EndD
 
Share this answer
 
Comments
CHill60 19-Jun-18 8:10am    
Gee thanks.
Why use in instead of =?
What if this is being used in Germany and the datename comes back as "Samstag"?

Edit - I just tried your code. It doesn't work, or you changed your requirements
kirthiga S 19-Jun-18 8:15am    
I have tried for multiple weeks

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900