Get day of the week in month (2nd Tuesday, etc.) - sql

I need an algorithm for calculating the number of the day of the week in the month. Like 1st Friday of the month, 3rd Monday of the month, etc.)
Any ideas are appreciated.
Here is the final result:
declare #dt date = GetDate()
declare #DayOfWeek tinyint = datepart(weekday,#dt)
declare #DayOfMonth smallint = day(#dt)
declare #FirstDayOfMonth date = dateadd(month,datediff(month,0,#dt),0)
declare #DayOfWeekInMonth tinyint = #DayOfMonth / 7 + 1 -
(case when day(#FirstDayOfMonth) > day(#dt) then 1 else 0 end)
declare #Suffix varchar(2) =
case
when #DayOfWeekInMonth = 1 then 'st'
when #DayOfWeekInMonth = 2 then 'nd'
when #DayOfWeekInMonth = 3 then 'rd'
when #DayOfWeekInMonth > 3 then 'th'
end
select
cast(#DayOfWeekInMonth as varchar(2))
+ #Suffix
+ ' '
+ datename(weekday,#Dt)
+ ' of '
+ datename(month,#dt)
+ ', '
+ datename(year,#Dt)
PS: And if you can think of a better way to state the problem, please do.

Followint code will give you 1st Wednesday of April 2014 for today:
SELECT cast((DATEPART(d, GETDATE() - 1) / 7) + 1 as varchar(12))
+ 'st ' + DATENAME(WEEKDAY, getdate()) + ' of ' +
DATENAME(month, getdate()) + ' ' + DATENAME(year, getdate());
For any date use the code below. It gives 5th Tuesday of April 2014 for #mydate = '2014-04-29' in the example:
DECLARE #mydate DATETIME;
SET #mydate = '2014-04-29';
SELECT
case
when DATEPART(d, #mydate) = 1 then cast((DATEPART(d, #mydate ) / 7) + 1 as varchar(12))
else cast((DATEPART(d, #mydate - 1) / 7) + 1 as varchar(12))
end
+
case
when (DATEPART(d, #mydate - 1) / 7) + 1 = 1 then 'st '
when (DATEPART(d, #mydate - 1) / 7) + 1 = 2 then 'nd '
when (DATEPART(d, #mydate - 1) / 7) + 1 = 3 then 'rd '
else 'th '
end
+ DATENAME(WEEKDAY, #mydate) + ' of ' +
DATENAME(month, #mydate) + ' ' + DATENAME(year, #mydate) as [Long Date Name]

Okeeeey my tuuuurn ,
Please rate my answer Metaphor hhh, Here's the cooode :
declare #v_month nvarchar(2) = '04'
,#v_annee nvarchar(4) = '2014'
declare #v_date date = convert(date,#v_annee+'-'+#v_month+'-01')
declare #v_date_2 date = dateadd(M,1,#v_date)
if OBJECT_ID('temp') is not null
drop table temp
create table temp(_date date, _DayOfMonth nvarchar(20), _order int)
while (#v_date<#v_date_2)
begin
set #v_date =#v_date;
WITH _DayOfWeek AS (
SELECT 1 id, 'monday' Name UNION ALL
SELECT 2 id, 'tuesday' Name UNION ALL
SELECT 3 id, 'wednesday' Name UNION ALL
SELECT 4 id, 'thursday' Name UNION ALL
SELECT 5 id, 'friday' Name UNION ALL
SELECT 6 id, 'saturday' Name UNION ALL
SELECT 7 id, 'sunday' Name)
insert into temp(_date,_DayOfMonth)
SELECT
#v_date
,(select Name from _DayOfWeek where id = DATEPART(WEEKDAY,#v_date))
SET #v_date = DATEADD(DAY,1,#v_date)
END
UPDATE tmp1
SET _order = _order_2
FROM temp tmp1
INNER JOIN
(SELECT *, ROW_NUMBER() OVER(PARTITION BY _DayOfMonth ORDER BY _date ASC) AS _order_2 FROM temp) tmp2
ON tmp1._date = tmp2._date
SELECT * FROM temp
SELECT *
FROM temp
WHERE _DayOfMonth = 'thursday'
AND _order = 3
I hope this will help you :)
Good Luck

OK, here's what I came up with, I'll +1 everyone who answered anyway:
declare #dt date = GetDate()
declare #DayOfWeek tinyint = datepart(weekday,#dt)
declare #DayOfMonth smallint = day(#dt)
declare #FirstDayOfMonth date = dateadd(month,datediff(month,0,#dt),0)
declare #DayOfWeekInMonth tinyint =
#DayOfMonth / 7 + 1
- (case when day(#FirstDayOfMonth) > day(#dt) then 1 else 0 end)
declare #Suffix varchar(2) =
case
when #DayOfWeekInMonth = 1 then 'st'
when #DayOfWeekInMonth = 2 then 'nd'
when #DayOfWeekInMonth = 3 then 'rd'
when #DayOfWeekInMonth > 3 then 'th'
end
select
cast(#DayOfWeekInMonth as varchar(2))
+ #Suffix
+ ' '
+ datename(weekday,#Dt)
+ ' of '
+ datename(month,#dt)
+ ', '
+ datename(year,#Dt)

declare #dt date = getdate()
declare #DayOfMonth smallint = datepart(d, #dt)
declare #Suffix varchar(2) =
case
when floor((#DayOfMonth - 1) / 7.0) = 0 then 'st' -- implies there were no such days previously in the month
when floor((#DayOfMonth - 1) / 7.0) = 1 then 'nd'
when floor((#DayOfMonth - 1) / 7.0) = 2 then 'rd'
else 'th'
end
select cast(floor((#DayOfMonth - 1) / 7.0) + 1 as varchar(1)) + #Suffix +
' ' + datename(weekday, #dt) + ' of ' + datename(month, #dt) +
', ' + datename(year, #dt)

DECLARE #dt DATETIME
SET #dt = DATEADD(d, 6, GETDATE())
SELECT #dt,
CAST((DAY(#dt) / 7) + CASE WHEN DATEPART(weekday, #dt) >= DATEPART(weekday, CAST(MONTH(#dt) AS NVARCHAR) + '/01/' + CAST(YEAR(#dt) AS NVARCHAR)) THEN 1 ELSE 0 END AS NVARCHAR)
+ '' + CASE (DAY(#dt) / 7) + CASE WHEN DATEPART(weekday, #dt) >= DATEPART(weekday, CAST(MONTH(#dt) AS NVARCHAR) + '/01/' + CAST(YEAR(#dt) AS NVARCHAR)) THEN 1 ELSE 0 END
WHEN 1 THEN N'st'
WHEN 2 THEN N'nd'
WHEN 3 THEN N'rd'
ELSE N'th'
END
+ ' ' + DATENAME(dw, #dt)
+ ' of ' + DATENAME(M, #dt)
+ ', ' + CAST(YEAR(#dt) AS NVARCHAR)
Result is a single SELECT (provided the assignment of #dt happened earlier) but is, essentially, the same logic as yours.

This following code will give you DATE for any day of the week in any month or year that you specify. All the variables that I have are to reduce repeating logic to improve code speed.
This code gives you date for 1st Monday in February in 2013
DECLARE #DayNumber INT = 1
,#DayWeekNumber INT = 2
,#MonthNumber INT = 2
,#YearNumber INT = 2013
,#FoM DATE
,#FoMWD INT;
SET #FoM = DATEFROMPARTS(#YearNumber,#MonthNumber,1)
SET #fomwd = DATEPART(WEEKDAY, #FoM);
SELECT CASE WHEN #fomwd = #DayWeekNumber THEN DATEADD(WEEK, #DayNumber - 1, #FoM)
WHEN #fomwd < #DayWeekNumber THEN DATEADD(DAY, #DayWeekNumber - #fomwd, DATEADD(WEEK, #DayNumber - 1, #FoM))
WHEN #fomwd > #DayWeekNumber THEN DATEADD(DAY, #DayWeekNumber - #fomwd, DATEADD(WEEK, #DayNumber, #FoM))
END AS DateOfDay;

Related

Finding time between two dates that excludes weekends and within a specific working time

I am trying to calculate the time taken between two dates within specific working hours.
Example:
Requested Date - 2022-02-17 16:30:00
Completion Date - 2022-02-21 07:00:00
Work Time - 07:30:00 - 17:00:00
Below is the script I have currently to filter out the weekend.
I am struggling to calculate the work time.
SELECT PN,ReqDate,CompDate,
(DATEDIFF(MINUTE,ReqDate,CompDate) - DATEDIFF(WK,ReqDate,CompDate) * 2880) +
CASE
WHEN DATEDIFF(WK,ReqDate,CompDate) = 1 AND DATEDIFF(DW,ReqDate,CompDate) <= 5 THEN 0
WHEN DATEDIFF(WK,ReqDate,CompDate) = 0 THEN 0
ELSE 1440
END AS TIMEMINUTES
FROM EXAMPLETABLE
WHERE ReqDate >= '2022-01-01'
I would loop over dates to find total working hours. Here is the sample code:
declare #WtStart varchar(9) = '07:30:00'
declare #WtEnd varchar(9) = '17:00:00'
declare #ReqDate datetime = '2022-02-17 16:30:00'
declare #CompDate datetime = '2022-02-21 07:00:00'
declare #TotMins int
select #TotMins = datediff(minute, #ReqDate, convert(varchar(8), #ReqDate, 112) + ' ' + #WtEnd)
declare #LoopDate datetime
select #LoopDate = dateadd(day, 1, convert(varchar(8), #ReqDate, 112))
while(1=1)
begin
if convert(varchar(8), #LoopDate, 112) = convert(varchar(8), #CompDate, 112)
begin
if #CompDate > convert(varchar(8), #LoopDate, 112) + ' ' + #WtStart
begin
select #TotMins = #TotMins + datediff(minute, convert(varchar(8), #LoopDate, 112) + ' ' + #WtStart, #CompDate)
end
break
end
if datepart(weekday, #LoopDate) not in(7, 1)
and not exists (select 1 from HolidayTable where d = #LoopDay
begin
select #TotMins = #TotMins + datediff(minute, '19700101 ' + #WtStart, '19700101 ' + #WtEnd)
end
select #LoopDate = dateadd(day, 1, #LoopDate)
end
select #TotMins / 60.0 "TotHours"

How Calculate Expire Date in SQL Query

I have this query for expiry date calculation and its work fine but result show in - eg:-9 year 4 month and 5 day.
I want to show that in normal way like "Expire in 9 years 4 months and 5 day":
DECLARE #TempDate Datetime ,
#ExpiryDate Datetime,
#year int,
#month int,
#day int
SET #ExpiryDate = (SELECT TOP (1) [ExpiryDate] FROM [dbo].[Purchases] WHERE [ProductId] = 1)
SELECT #TempDate = #ExpiryDate
SELECT
#year = DATEDIFF(YEAR, #TempDate, GETDATE()) -
CASE
WHEN (MONTH(#ExpiryDate) > MONTH(GETDATE())) OR
(MONTH(#ExpiryDate) = MONTH(GETDATE()) AND DAY(#ExpiryDate) > DAY(GETDATE()))
THEN 1 ELSE 0
END
SELECT #TempDate = DATEADD(YEAR, #year, #TempDate)
SELECT #month = DATEDIFF(MONTH, #TempDate, GETDATE()) -
CASE
WHEN DAY(#ExpiryDate) > DAY(GETDATE())
THEN 1 ELSE 0
END
SELECT #TempDate = DATEADD(MONTH, #month, #TempDate)
SELECT #day = DATEDIFF(DAY, #TempDate, GETDATE())
SELECT #year AS Years, #month AS Months, #day AS [Days]
If I understand your question correctly, the calculation is working as you expect but you want the Years value to be returned as a positive rather than negative number. If this is the case, you should change the final SELECT to:
SELECT (#year * -1) AS Years, #month AS Months, #day AS [Days];
Alternatively if you want to return the output as a string (i.e. Expire in 9 years 4 months and 5 day), change the final SELECT to:
SELECT 'Expire in ' + CAST((#year * -1) AS VARCHAR(2)) + ' years '
+ CAST(#month AS VARCHAR(2)) + ' months and '
+ CAST(#day AS VARCHAR(2)) + ' day';
Casting as VARCHAR(2) assumes that you expect no more than 99 years, but you may want to increase that number.

Get date difference in year, month, and days SQL

Is there a way to calculate how old someone is based on today's date and their birthday then display it in following manners:
If a user is less than (<) 1 year old THEN show their age in MM & days.
Example: 10 months & 2 days old
If a user is more than 1 year old AND less than 6 years old THEN show their age in YY & MM & days.
Example: 5 years & 3 months & 10 days old
If a user is more than 6 years old THEN display their age in YY.
Example: 12 years
This is basically what you are looking for:
DECLARE #date1 DATETIME
, #date2 DATETIME;
SELECT #date1 = '1/1/2008'
, #date2 = GETDATE();
SELECT CASE
WHEN DATEDIFF(YEAR, #date1, #date2) < 1 THEN CAST(DATEDIFF(mm, #date1, #date2) AS VARCHAR)+' Months & '+CAST(DATEDIFF(dd, DATEADD(mm, DATEDIFF(mm, #date1, #date2), #date1), #date2) AS VARCHAR)+' Days'
WHEN DATEDIFF(YEAR, #date1, #date2) BETWEEN 1 AND 5 THEN CAST(DATEDIFF(mm, #date1, #date2) / 12 AS VARCHAR)+' Years & '+CAST(DATEDIFF(mm, #date1, #date2) % 12 AS VARCHAR)+' Months'
WHEN DATEDIFF(YEAR, #date1, #date2) >= 6 THEN CAST(DATEDIFF(YEAR, #date1, #date2) AS VARCHAR)+' Years'
END;
Result for when a user is less than (<) 1 year old THEN show their age in MM & days:
Result for when a user is more than 1 year old AND less than 6 years old THEN show their age in YY & MM & days:
Result for when a user is more than 6 years old THEN display their age in YY:
from this previous question
How to calculate age in T-SQL with years, months, and days
you can do procedure like this
CREATE procedure [dbo].[proc_datediff]
(
#date datetime
)
as
begin
DECLARE #diff varchar(70)
DECLARE #tmpdate datetime, #years int, #months int, #days int
SELECT #tmpdate = #date
SELECT #years = DATEDIFF(yy, #tmpdate, GETDATE()) - CASE WHEN
(MONTH(#date) > MONTH(GETDATE())) OR (MONTH(#date) =
MONTH(GETDATE()) AND DAY(#date) > DAY(GETDATE())) THEN 1 ELSE 0 END
SELECT #tmpdate = DATEADD(yy, #years, #tmpdate)
SELECT #months = DATEDIFF(m, #tmpdate, GETDATE()) - CASE WHEN
DAY(#date) > DAY(GETDATE()) THEN 1 ELSE 0 END
SELECT #tmpdate = DATEADD(m, #months, #tmpdate)
SELECT #days = DATEDIFF(d, #tmpdate, GETDATE())
select #diff=
case
when #years < 1 then
concat( #months,' Months ',#days,' days ' )
when #years >=1 and #years < 6
then
concat(#years,' year ', #months,' Months ',#days,' days ' )
when #years >= 6 then
concat( #years,' years ' )
end;
select #diff
end
execute proc_datediff '1/1/2016'
go
CREATE FUNCTION [dbo].[FindDateDiff](#Date1 date,#Date2 date, #IncludeTheEnDate bit)
RETURNS TABLE
AS
RETURN
(
SELECT
CALC.Years,CALC.Months,D.Days,
Duration = RTRIM(Case When CALC.Years > 0 Then CONCAT(CALC.Years, ' year(s) ') Else '' End
+ Case When CALC.Months > 0 Then CONCAT(CALC.Months, ' month(s) ') Else '' End
+ Case When D.Days > 0 OR (CALC.Years=0 AND CALC.Months=0) Then CONCAT(D.Days, ' day(s)') Else '' End)
FROM (VALUES(IIF(#Date1<#Date2,#Date1,#Date2),DATEADD(DAY, IIF(#IncludeTheEnDate=0,0,1), IIF(#Date1<#Date2,#Date2,#Date1)))) T(StartDate, EndDate)
CROSS APPLY(Select
TempEndYear = Case When ISDATE(CONCAT(YEAR(T.EndDate), FORMAT(T.StartDate,'-MM-dd')))=1 Then CONCAT(YEAR(T.EndDate), FORMAT(T.StartDate,'-MM-dd'))
Else CONCAT(YEAR(T.EndDate),'-02-28') End
) TEY
CROSS APPLY(Select EndYear = Case When TEY.TempEndYear > T.EndDate Then DATEADD(YEAR, -1, TEY.TempEndYear) Else TEY.TempEndYear End) EY
CROSS APPLY(Select
Years = DATEDIFF(YEAR,T.StartDate,EY.EndYear),
Months = DATEDIFF(MONTH,EY.EndYear,T.EndDate)-IIF(DAY(EY.EndYear)>DAY(T.EndDate),1,0)
) CALC
CROSS APPLY(Select Days = DATEDIFF(DAY,DATEADD(MONTH,CALC.Months,DATEADD(YEAR,CALC.Years,T.StartDate)),T.EndDate)) D
)
Sample:
Select [From] = '2021-01-01',[To] = '2021-12-31',IncludeEndDate='Yes',* From dbo.FindDateDiff('2021-01-01','2021-12-31',1)
Select [From] = '2021-01-01',[To] = '2021-12-31',IncludeEndDate='No',* From dbo.FindDateDiff('2021-01-01','2021-12-31',0)
Select [From] = '2015-12-15',[To] = '2018-12-14',IncludeEndDate='Yes',* From dbo.FindDateDiff('2015-12-15','2018-12-14',1)
Select [From] = '2015-12-15',[To] = '2018-12-14',IncludeEndDate='No',* From dbo.FindDateDiff('2015-12-15','2018-12-14',0)
Probably not the most efficient way to go about it, but here's how I did it:
I had to first get the date difference between today's date and person's birthdate. I used it to get years, months, days, etc by combining it with ABS(), and Remainder (%) function.
declare #year int = 365
declare #month int = 30
declare #sixYears int = 2190
select
--CAST(DATEDIFF(mm, a.BirthDateTime, getdate()) AS VARCHAR) as GetMonth,
--CAST(DATEDIFF(dd, DATEADD(mm, DATEDIFF(mm, a.BirthDateTime, getdate()), a.BirthDateTime), getdate()) AS VARCHAR) as GetDays,
CASE
WHEN
DATEDIFF(dd,a.BirthDateTime,getdate()) < #year
THEN
cast((DATEDIFF(dd,a.BirthDateTime,getdate()) / (#month)) as varchar) +' Months & ' +
CAST(ABS(DATEDIFF(dd, DATEADD(mm, DATEDIFF(mm, a.BirthDateTime, getdate()), a.BirthDateTime), getdate())) AS VARCHAR)
+ ' Days'
WHEN
DATEDIFF(dd,a.BirthDateTime,getdate()) between #year and #sixYears
THEN
cast((DATEDIFF(dd,a.BirthDateTime,getdate()) / (#year)) as varchar) +' Years & ' +
CAST((DATEDIFF(mm, a.BirthDateTime, getdate()) % (12)) AS VARCHAR) + ' Months'
WHEN DATEDIFF(dd,a.BirthDateTime,getdate()) > #sixYears
THEN cast(a.Age as varchar) + ' Years'
end as FinalAGE,
dc.DayMarker = cast(getdate() as date)
DAYmarker is your date field.

SQL Query - Have to determine if it is a specific day of the month (ex: 2 Tuesday of month)

I have an app that allows users schedule an action to occur in the future. For example, that can select a date and schedule it to run on that day every month (ex: the 15th of each month). However, I now need to allow them to select a week day and week of the month. For example, they need to run an action the first friday of the month. Therefore I am allowing the to select the weekday (monday, tuesday, wednesday....) and week of the month (1st, 2nd, 3rd, 4th or 5th).
Here is the query I currently use:
Declare #nowString varchar(19)
Declare #nowDateString varchar(19)
Declare #now datetime
Declare #lastMinute datetime
Declare #nowDate datetime
Set #nowString = '#currentDateTime#:00'
Set #nowDateString = LEFT(#nowString, 10)
set #now = #nowString
set #nowDate = DATEADD(dd, 0, DATEDIFF(dd, 0, #now))
set #lastMinute = DATEADD(mi, -1, #now)
select *
from message_prepared
where schedule = '1'
and active = '1'
and noaa = '0'
and (
(
schedule_type = 'recurring'
and startdate <= #nowDate
and isnull(enddate, DATEADD(yy, 1, #nowDate)) >= #nowDate
and (
#nowDateString + ' ' + isnull(recurring_start_time_hour, '00') + ':' + isnull(recurring_start_time_min, '00') + ':00' = #now
or #nowDateString + ' ' + isnull(recurring_start_time_hour, '00') + ':' + isnull(recurring_start_time_min, '00') + ':00' = #lastMinute
)
-- Test for different type of recurring
and (
( ltrim(rtrim(recurring)) = 'M' and DATEPART(dd, startdate) = DATEPART(dd, #now) )
or ( ltrim(rtrim(recurring)) = 'W' and DATEPART(dw, startdate) = DATEPART(dw, #now) )
or ltrim(rtrim(recurring)) = 'D'
)
)
or (
schedule_type = 'once'
and startdate = #nowDate
and (
#nowDateString + ' ' + onetime_start_time_hour + ':' + onetime_start_time_min + ':00' = #now
or #nowDateString + ' ' + onetime_start_time_hour + ':' + onetime_start_time_min + ':00' = #lastMinute
)
)
)
and repeat_multiple_times = 0
UNION ALL
SELECT *
FROM MESSAGE_PREPARED
WHERE schedule = '1'
AND active = 1
AND noaa = 0
AND recurring = 'D'
AND repeat_multiple_times = 1
AND startDate IS NOT NULL
AND recurring_start_time_hour IS NOT NULL
AND recurring_start_time_hour < 24
AND recurring_start_time_min IS NOT NULL
AND recurring_start_time_min < 60
AND startdate <= #nowDate
AND ISNULL(enddate, DATEADD(yy, 1, #nowDate)) >= #nowDate
AND
(
CASE WHEN repeat_unit = 'M'
THEN
DATEDIFF(n,
CONVERT(DATETIME,
CAST(DATEPART(yyyy, startDate) AS VARCHAR(4)) + '-' +
CAST(DATEPART(mm, startDate) AS VARCHAR(2)) + '-' +
CAST(DATEPART(dd, startDate) AS VARCHAR(2)) + ' ' +
CAST(recurring_start_time_hour AS VARCHAR(2)) + ':' +
CAST(recurring_start_time_min AS VARCHAR(2)) + ':00', 20),
GETDATE()) % repeat_interval
ELSE
DATEDIFF(n,
CONVERT(DATETIME,
CAST(DATEPART(yyyy, startDate) AS VARCHAR(4)) + '-' +
CAST(DATEPART(mm, startDate) AS VARCHAR(2)) + '-' +
CAST(DATEPART(dd, startDate) AS VARCHAR(2)) + ' ' +
CAST(recurring_start_time_hour AS VARCHAR(2)) + ':' +
CAST(recurring_start_time_min AS VARCHAR(2)) + ':00', 20),
GETDATE()) % (repeat_interval * 60)
END = 0
OR
CASE WHEN repeat_unit = 'M'
THEN
(DATEDIFF(n,
CONVERT(DATETIME,
CAST(DATEPART(yyyy, startDate) AS VARCHAR(4)) + '-' +
CAST(DATEPART(mm, startDate) AS VARCHAR(2)) + '-' +
CAST(DATEPART(dd, startDate) AS VARCHAR(2)) + ' ' +
CAST(recurring_start_time_hour AS VARCHAR(2)) + ':' +
CAST(recurring_start_time_min AS VARCHAR(2)) + ':00', 20),
GETDATE()) - 1) % repeat_interval
ELSE
(DATEDIFF(n,
CONVERT(DATETIME,
CAST(DATEPART(yyyy, startDate) AS VARCHAR(4)) + '-' +
CAST(DATEPART(mm, startDate) AS VARCHAR(2)) + '-' +
CAST(DATEPART(dd, startDate) AS VARCHAR(2)) + ' ' +
CAST(recurring_start_time_hour AS VARCHAR(2)) + ':' +
CAST(recurring_start_time_min AS VARCHAR(2)) + ':00', 20),
GETDATE()) - 1) % (repeat_interval * 60)
END = 0
)
This will only occur when reocurring is set to "M" and I would like to determine if today is the specific day of the week, week of the month and hour/min.
This is pretty simple logic. Today is the nth DOW of the month when the following is true:
Today is that day of the week
The day of the month is between 7*(n-1) + 1 and 7 * n
So, the first Monday of the month is always between the 1st and 7th, and so on. Here is an example case statement to test this:
declare #DayOfWeek varchar(255) = 'Thursday';
declare #Which int = 3;
select (case when datename(dw, Today) = #DayOfWeek and
(DAY(Today) - 1) / 7 = #Which - 1
then 1
else 0
end)
from (select CAST(getdate() as date) as Today) t
I've structured the query this way so you can test it with different values. Just replace the expression that defines Today, with something like getdate() - 3 or '2013-01-01'.

INNER JOIN code calculated value with SELECT statement

I have the following stored procedure which will generate mon to sun and then creates a temp table with a series of 'weeks' (start and end weeks) :
USE [test_staff]
GO
/****** Object: StoredProcedure [dbo].[sp_timesheets_all_staff_by_week_by_job_grouping_by_site] Script Date: 03/21/2012 09:04:49 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[sp_timesheets_all_staff_by_week_by_job_grouping_by_site]
(
#grouping_ref int,
#week_ref int
)
AS
CREATE TABLE #WeeklyList
(
Start_Week date,
End_Week date,
week_ref int
--month_name date
)
DECLARE #REPORT_DATE DATETIME, #WEEK_BEGINING VARCHAR(10)
SELECT #REPORT_DATE = '2011-01-19T00:00:00'
--SELECT #REPORT_DATE = GETDATE() -- should grab the date now.
SELECT #WEEK_BEGINING = 'MONDAY'
IF #WEEK_BEGINING = 'MONDAY'
SET DATEFIRST 1
ELSE IF #WEEK_BEGINING = 'TUESDAY'
SET DATEFIRST 2
ELSE IF #WEEK_BEGINING = 'WEDNESDAY'
SET DATEFIRST 3
ELSE IF #WEEK_BEGINING = 'THURSDAY'
SET DATEFIRST 4
ELSE IF #WEEK_BEGINING = 'FRIDAY'
SET DATEFIRST 5
ELSE IF #WEEK_BEGINING = 'SATURDAY'
SET DATEFIRST 6
ELSE IF #WEEK_BEGINING = 'SUNDAY'
SET DATEFIRST 7
DECLARE #WEEK_START_DATE DATETIME, #WEEK_END_DATE DATETIME
--GET THE WEEK START DATE
SELECT #WEEK_START_DATE = #REPORT_DATE - (DATEPART(DW, #REPORT_DATE) - 1)
--GET THE WEEK END DATE
SELECT #WEEK_END_DATE = #REPORT_DATE + (7 - DATEPART(DW, #REPORT_DATE))
PRINT 'Week Start: ' + CONVERT(VARCHAR, #WEEK_START_DATE)
PRINT 'Week End: ' + CONVERT(VARCHAR, #WEEK_END_DATE)
DECLARE #Interval int = datediff(WEEK,getdate(),#WEEK_START_DATE)+1
--SELECT Start_Week=#WEEK_START_DATE
--, End_Week=#WEEK_END_DATE
--INTO #WeekList
INSERT INTO #WeeklyList
SELECT Start_Week=#WEEK_START_DATE, End_Week=#WEEK_END_DATE
WHILE #Interval <= 0
BEGIN
set #WEEK_START_DATE=DATEADD(WEEK,1,#WEEK_START_DATE)
set #WEEK_END_DATE=DATEADD(WEEK,1,#WEEK_END_DATE)
INSERT INTO #WeeklyList values (#WEEK_START_DATE,#WEEK_END_DATE)
SET #Interval += 1;
END
SELECT
CONVERT(VARCHAR(11), Start_Week, 106) AS 'month_name',
CONVERT(VARCHAR(11), End_Week, 106) AS 'End',
DATEDIFF(DAY, 0, Start_Week) / 7 AS week_ref -- create the unique week reference number
--'VIEW' AS month_name
FROM #WeeklyList
In this section i am creating the week_ref
DATEDIFF(DAY, 0, Start_Week) / 7 AS week_ref -- create the unique week reference number
I then need to combine it with this select code:
DECLARE #YearString char(3) = CONVERT(char(3), SUBSTRING(CONVERT(char(5), #week_ref), 1, 3))
DECLARE #MonthString char(2) = CONVERT(char(2), SUBSTRING(CONVERT(char(5), #week_ref), 4, 2))
--Convert:
DECLARE #Year int = CONVERT(int, #YearString) + 1200
DECLARE #Month int = CONVERT(int, #MonthString)
**--THIS FILTERS THE REPORT**
SELECT ts.staff_member_ref, sm.common_name, sm.department_name, DATENAME(MONTH, ts.start_dtm) + ' ' + DATENAME(YEAR, ts.start_dtm) AS month_name,
ts.timesheet_cat_ref, cat.desc_long AS timesheet_cat_desc, grps.grouping_ref, grps.description AS grouping_desc, ts.task_ref, tsks.task_code,
tsks.description AS task_desc, ts.site_ref, sits.description AS site_desc, ts.site_ref AS Expr1,
CASE WHEN ts .status = 0 THEN 'Pending' WHEN ts .status = 1 THEN 'Booked' WHEN ts .status = 2 THEN 'Approved' ELSE 'Invalid Status' END AS site_status,
ts.booked_time AS booked_time_sum,
start_dtm, CONVERT(varchar(20), start_dtm, 108) + ' ' + CONVERT(varchar(20), start_dtm, 103) AS start_dtm_text, booked_time,
end_dtm, CONVERT(varchar(20), end_dtm, 108) + ' ' + CONVERT(varchar(20), end_dtm, 103) AS end_dtm_text
FROM timesheets AS ts INNER JOIN
timesheet_categories AS cat ON ts.timesheet_cat_ref = cat.timesheet_cat_ref INNER JOIN
timesheet_tasks AS tsks ON ts.task_ref = tsks.task_ref INNER JOIN
timesheet_task_groupings AS grps ON tsks.grouping_ref = grps.grouping_ref INNER JOIN
timesheet_sites AS sits ON ts.site_ref = sits.site_ref INNER JOIN
vw_staff_members AS sm ON ts.staff_member_ref = sm.staff_member_ref
WHERE (ts.status IN (1, 2)) AND (cat.is_leave_category = 0)
GROUP BY ts.staff_member_ref, sm.common_name, sm.department_name, DATENAME(MONTH, ts.start_dtm), DATENAME(YEAR, ts.start_dtm), ts.timesheet_cat_ref,
cat.desc_long, grps.grouping_ref, grps.description, ts.status, ts.booked_time, ts.task_ref, tsks.task_code, tsks.description, ts.site_ref, sits.description, ts.start_dtm,
ts.end_dtm
ORDER BY sm.common_name, timesheet_cat_desc, tsks.task_code, site_desc
DROP TABLE #WeeklyList
GO
I want to pass the week_ref into the SELECT statement (refer to comment - THIS FILTERS THE REPORT) but the problem is week_ref isnt a valid column as its derived by code.
Any ideas?
Just perform an INNER JOIN to your weeklylist temp table on the date you need to filter.
I am not sure that I really understand the problem but I found 2 problems in the code you posted.
The inserts you make on the #WeeklyList temporary table, are missing one column in the selected values that I assume you wanted to be your variable #week_ref
I I change this, I get to the point of the final table select that I dont have.
hope this is a start to solve your problem