Hi can someone please help me, I want to create a script with a month parameter, the results I require is the next 12 month's names as column headings.
For example if the parameter is February the results should be:
March | April | May | June | July | August | September | October | November | December | January | February |
As the column names which I want to use to fill in values at a later stage.
Can someone please advise me on this and how I can achieve this
My script I have so far don't know how to approach this
declare #MonthParam varchar(20) = 'March'
declare #MonthNumber int = (
Select CASE WHEN #MonthParam = 'January' THEN 1
WHEN #MonthParam = 'February' THEN 2
WHEN #MonthParam = 'March' THEN 3
WHEN #MonthParam = 'April' THEN 4
WHEN #MonthParam = 'May' THEN 5
WHEN #MonthParam = 'June' THEN 6
WHEN #MonthParam = 'July' THEN 7
WHEN #MonthParam = 'August' THEN 8
WHEN #MonthParam = 'September' THEN 9
WHEN #MonthParam = 'October' THEN 10
WHEN #MonthParam = 'November' THEN 11
WHEN #MonthParam = 'December' THEN 12
END)
WHILE(#MonthNumber < 13)
BEGIN
declare #month varchar(20) = DateName( month , DateAdd( month , #MonthNumber , 0 ) - 1 )
declare #sql varchar(max)
set #sql = 'select val as ' + #month + ' from t'
exec (#sql)
SET #MonthNumber = #MonthNumber + 1;
END
Other wise you can use the "simplified" approach.
declare #MonthParam varchar(20) = 'March'
declare #Dte date = CAST(concat(#MonthParam, ' 01 1900') AS DATE)
declare #sql varchar(max) = concat('select null as ', DATENAME(MONTH, DATEADD(MONTH, 1, #Dte)),
', null as ', DATENAME(MONTH, DATEADD(MONTH, 2, #Dte)),
',null as ',DATENAME(MONTH, DATEADD(MONTH, 3, #Dte)),
',null as ',DATENAME(MONTH, DATEADD(MONTH, 4, #Dte)),
',null as ',DATENAME(MONTH, DATEADD(MONTH, 5, #Dte)),
',null as ',DATENAME(MONTH, DATEADD(MONTH, 6, #Dte)),
',null as ',DATENAME(MONTH, DATEADD(MONTH, 7, #Dte)),
',null as ',DATENAME(MONTH, DATEADD(MONTH, 8, #Dte)),
',null as ',DATENAME(MONTH, DATEADD(MONTH, 9, #Dte)),
',null as ',DATENAME(MONTH, DATEADD(MONTH, 10, #Dte)),
',null as ',DATENAME(MONTH, DATEADD(MONTH, 11, #Dte)),
',null as ',DATENAME(MONTH, DATEADD(MONTH, 12, #Dte)))
exec (#sql)
declare #date_entered varchar(50) = 'February'
set #date_entered = #date_entered + ' 01 ' + CONVERT(char(4),year(getdate()))
declare #start_month datetime = #date_entered
declare #loop_month datetime = #start_month
declare #sql nvarchar(max)
set #sql = 'CREATE TABLE MyDates ('
WHILE #loop_month < DATEADD(year,1,#start_month)
BEGIN
set #sql += DATENAME(month,#loop_month) + ' varchar(100),'
set #loop_month = DATEADD(month,1,#loop_month)
END
-- Get rid of the comma at the end of the string and close the table paranthesis (edit was to the following bit)
set #sql = LEFT(#sql,len(#sql)-1) + ')'
print #sql
--Uncomment below to run
--exec(#sql)
I've used a temp table with some dummy data to show the final output as a table
DECLARE #PivotColumnHeaders VARCHAR(MAX);
DECLARE #date_entered varchar(50) = 'February';
SET #date_entered = #date_entered + ' 01 ' + CONVERT(CHAR(4),YEAR(GETDATE()));
DECLARE #s INT= 1, #e INT = 12;
CREATE TABLE PivotTemp (Dummy INT, [MonthName] VARCHAR(15));
WHILE ( #s <= #e)
BEGIN
SELECT #PivotColumnHeaders =
COALESCE(
#PivotColumnHeaders + ',[' + DATENAME(MONTH,DATEADD(MONTH, #s, #date_entered)) + ']',
'[' + DATENAME(MONTH,DATEADD(MONTH, #s, #date_entered))+ ']'
);
INSERT INTO PivotTemp ( Dummy, [MonthName] ) VALUES ( #s, DATENAME(MONTH,DATEADD(MONTH, #s, #date_entered)) );
SET #s = #s + 1;
END;
--SELECT #PivotColumnHeaders ;
--SELECT * FROM PivotTemp ;
DECLARE #PivotTableSQL NVARCHAR(MAX);
SET #PivotTableSQL = N'
SELECT *
FROM (
SELECT
H.Dummy [DummyValue],
H.[MonthName] [MonthName]
FROM dbo.PivotTemp H
) AS PivotData
PIVOT (
MAX(DummyValue)
FOR [MonthName] IN (
' + #PivotColumnHeaders + '
)
) AS PivotTable
';
EXECUTE(#PivotTableSQL);
DROP TABLE PivotTemp;
Related
Overview : I want to show the weekly result by input parameters startdate and enddate. I am getting this result quite well. But the problem here is, When i want start date from 28/08/2015 from end date 04/09/2015 am getting 28, 29, 30, 31, 01, 02, 03, 04 from same month(august). Expected result should be 28, 29, 30, 31 from august and 01, 02, 03, 04 from september.
Help me to overcome this problem. Below is my code
ALTER PROCEDURE [dbo].[usp_Get_TimesheetDetails]
#UserID int, #startdate datetime, #enddate datetime
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
declare #intStartDate int
declare #intEndDate int, #diff int
declare #strMonth varchar(50)
Select #intStartDate = DATEPART(day, #startDate)
Select #intEndDate = DATEPART(day, #endDate)
select #strMonth = DATENAME(MONTH, GETDATE())
Declare #temptable table (num date )
Declare #columns varchar(max)
DECLARE #sqlText nvarchar(1000);
DECLARE #startnum INT = #intStartDate-1
DECLARE #endnum INT = #intEndDate
select #diff = DATEDIFF(MONTH, #startdate, #enddate)
;WITH gen AS (
SELECT #startdate AS num
UNION ALL
SELECT DATEADD(DAY,1,num) FROM gen
WHERE DATEADD(DAY,1,num) <= #enddate
)
insert into #temptable SELECT num FROM gen
option (maxrecursion 10000)
set #columns=
(SELECT distinct
STUFF((SELECT ',' + CAST( DATEPART(DAY, num) as varchar(100)) [text()]
FROM #temptable
FOR XML PATH(''), TYPE)
.value('.','NVARCHAR(MAX)'),1,2,' ') List_Output
FROM #temptable t)
if(#startnum < 10)
BEGIN
SET #sqlText = N'SELECT ' + STUFF(REPLACE(#columns,',','],['),1,3,'') + ']' + ' FROM dbo.timesheet where month ='''+ #strMonth+''' and [Task ID] in(select TaskID from ManageTasks where TeamMemberUserID ='+ Cast(#UserID AS VARCHAR(max)) +')'
print #sqlText
END
else if(#startnum >= 10)
BEGIN
SET #sqlText = N'SELECT ' + STUFF(REPLACE(#columns,',','],['),1,4,'') + ']' + ' FROM dbo.timesheet where month ='''+ #strMonth+''' and [Task ID] in(select TaskID from ManageTasks where TeamMemberUserID ='+ Cast(#UserID AS VARCHAR(max)) +')'
END
print #sqlText
Exec (#sqlText)
end
end
Edited : I tried with if else condition like, if(monthdifference is equal to 0)
else(monthdifference is greater than 0). But not getting expected result.
try this
Declare
#StartDate datetime='2015/08/28',
#EndDate datetime='2015/09/04'
;WITH sample AS (
SELECT CAST(#StartDate AS DATETIME) AS dt
UNION ALL
SELECT DATEADD(dd, 1, dt)
FROM sample s
WHERE DATEADD(dd, 1, dt) <= CAST(#EndDate AS DATETIME))
SELECT *
FROM sample
output is :
2015-08-28 00:00:00.000
2015-08-29 00:00:00.000
2015-08-30 00:00:00.000
2015-08-31 00:00:00.000
2015-09-01 00:00:00.000
2015-09-02 00:00:00.000
2015-09-03 00:00:00.000
2015-09-04 00:00:00.000
Original Link : https://stackoverflow.com/a/3946151/3465753
Make sure you declared startdate as well as enddate in dynamic query
The main Ideas are:
You don't need to use STUFF. Just select dates from DATEADD(DAY,1,#startdate)
You should get dates twise if DATENAME(MONTH, #startdate)!=DATENAME(MONTH, #enddate). First time from startdate to end of months. Second time from start of second month to enddate.
My (checked) script.
ALTER PROCEDURE [dbo].[usp_Get_TimesheetDetails]
#UserID int, #startdate datetime, #enddate datetime
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
Declare #columns varchar(max);
DECLARE #sqlText nvarchar(1000);
Declare #temptable table (num date );
WITH gen AS (
SELECT DATEADD(DAY,1,#startdate) AS num
UNION ALL
SELECT DATEADD(DAY,1,num) FROM gen
WHERE DATEADD(DAY,1,num) <= #enddate
and DATEADD(DAY,1,num) < dateadd(month,datediff(month,0,#enddate),0)
)
insert into #temptable SELECT num FROM gen
option (maxrecursion 10000)
set #columns=
(SELECT distinct
STUFF((SELECT ',' + CAST( DATEPART(DAY, num) as varchar(100)) [text()]
FROM #temptable
FOR XML PATH(''), TYPE)
.value('.','NVARCHAR(MAX)'),1,1,'') List_Output
FROM #temptable t)
SET #sqlText = N'SELECT [' + REPLACE(#columns,',','],[') + ']' + ' FROM dbo.timesheet where month ='''+ DATENAME(MONTH, #startdate)+''' and [Task ID] in(select TaskID from ManageTasks where TeamMemberUserID ='+ Cast(#UserID AS VARCHAR(max)) +')';
print #sqlText;
IF DATENAME(MONTH, #startdate)!=DATENAME(MONTH, #enddate)
BEGIN
delete from #temptable;
WITH gen AS (
SELECT dateadd(month,datediff(month,0,#enddate),0) AS num
UNION ALL
SELECT DATEADD(DAY,1,num) FROM gen
WHERE DATEADD(DAY,1,num) <= #enddate
)
insert into #temptable SELECT num FROM gen
option (maxrecursion 10000)
set #columns=
(SELECT distinct
STUFF((SELECT ',' + CAST( DATEPART(DAY, num) as varchar(100)) [text()]
FROM #temptable
FOR XML PATH(''), TYPE)
.value('.','NVARCHAR(MAX)'),1,1,'') List_Output
FROM #temptable t)
SET #sqlText = N'SELECT [' + REPLACE(#columns,',','],[') + ']' + ' FROM dbo.timesheet where month ='''+ DATENAME(MONTH, #enddate)+''' and [Task ID] in(select TaskID from ManageTasks where TeamMemberUserID ='+ Cast(#UserID AS VARCHAR(max)) +')';
print #sqlText
end
end
You might find pivot/unpivot to be more robust. Certainly your table design is not ideal. (I pared down the number of columns for demonstration purposes.)
create table dbo.timesheet (
[month] varchar(12) not null,
[1] int null, [2] int null, [3] int null,
[28] int null, [29] int null, [30] int null, [31] int null
);
declare #startDate date = '20160628';
declare #endDate date = '20160703';
insert into dbo.timesheet ([month], [1], [2], [3], [28], [29], [30], [31])
values ('June', 1, 2, 3, 4, 5, 6, null), ('July', 8, 9, 10, 11, 12, 13, 14);
with hrs as (
select
hrs,
dy,
dateadd(
month,
case [month]
when 'January' then 1 when 'February' then 2 when 'March' then 3
when 'April' then 4 when 'May' then 5 when 'June' then 6
when 'July' then 7 when 'August' then 8 when 'September' then 9
when 'October' then 10 when 'November' then 11 when 'December' then 12
end,
dateadd(year, year(getdate()) - 2000, dateadd(day, dy - 1, '19991201'))
) as dt
from
(select [month], [1], [2], [3], [28], [29], [30], [31] from dbo.timesheet) t
unpivot (hrs for dy in ([1], [2], [3], [28], [29], [30], [31])) as upvt
)
select datename(month, dt), [1], [2], [3], [28], [29], [30], [31]
from hrs pivot (min(hrs) for dy in ([1], [2], [3], [28], [29], [30], [31])) as pvt
where dt between #startDate and #endDate;
I have following script where I need to get the full date
DECLARE #BeginDate DateTime
DECLARE #EndDate DateTime
Declare #month int
Declare #year int
set #month = 6
set #year = 2014
Select beginDate = CAST(#month AS VARCHAR(10)) + '/01/' + CAST(#year AS VARCHAR(10))
SELECT endDate = DATEADD(d, -1, DATEADD(m, DATEDIFF(m, 0, #beginDate) + 1, 0))
This script returns endDate as null. How do I get full endDate by passing only Date (not time)?
I think you forgot to put # sign in front of the variables. If you change the last two lines with the following:
Select #beginDate = CAST(#month AS VARCHAR(10)) + '/01/' + CAST(#year AS VARCHAR(10))
SELECT #endDate = DATEADD(d, -1, DATEADD(m, DATEDIFF(m, 0, #beginDate) + 1, 0))
it should work. By putting "select #enddate" at the end, I got 2014-06-30 00:00:00.000 .
Well I found it.
DECLARE #BeginDate DateTime
DECLARE #EndDate DateTime
Declare #month int
Declare #year int
set #month = 7
set #year = 2014
Select #beginDate = CAST(#month AS VARCHAR(10)) + '/01/' + CAST(#year AS VARCHAR(10))
SELECT endDate = DATEADD(d, -DAY(DATEADD(mm, 1, #beginDate)), DATEADD(m, 1, #BeginDate))
source
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;
I'm creating function to return me a number of worked minutes between two dates.
This returns me the exact number of minuts but when I use it on many records, the treatment is very long.
I have 3 functions:
CREATE FUNCTION FN_FERIES_SELON_ANNEE (#YEAR INT)
RETURNS #FERIES TABLE (JourId INT NOT NULL,
JourDate DATETIME NOT NULL,
JoURLabel VARCHAR(50) NULL)
AS
BEGIN
DECLARE #JoursFeries TABLE (
[JourId] [INT] IDENTITY(1,1) NOT NULL,
[JourDate] [DATETIME] NOT NULL,
[JoURLabel] [VARCHAR](50) NULL
)
DECLARE #an INT
DECLARE #G INT
DECLARE #I INT
DECLARE #J INT
DECLARE #C INT
DECLARE #H INT
DECLARE #L INT
DECLARE #JourPaque INT
DECLARE #MoisPaque INT
DECLARE #DimPaque DATETIME
DECLARE #LunPaque DATETIME
DECLARE #JeuAscension DATETIME
DECLARE #LunPentecote DATETIME
DECLARE #NouvelAn DATETIME
DECLARE #FeteTravail DATETIME
DECLARE #Armistice3945 DATETIME
DECLARE #Assomption DATETIME
DECLARE #Armistice1418 DATETIME
DECLARE #FeteNationale DATETIME
DECLARE #ToussaINT DATETIME
DECLARE #Noel DATETIME
SET #an = #YEAR
SET #G = #an % 19
SET #C = #an / 100
SET #H = (#C - #C / 4 - (8 * #C + 13) / 25 + 19 * #G + 15) % 30
SET #I = #H - (#H / 28) * (1 - (#H / 28) * (29 / (#H + 1)) * ((21 - #G) / 11))
SET #J = (#an + #an / 4 + #I + 2 - #C + #C / 4) % 7
SET #L = #I - #J
SET #MoisPaque = 3 + (#L + 40) / 44
SET #JourPaque = #L + 28 - 31 * (#MoisPaque / 4)
-- Jours fériés mobiles
SET #DimPaque = cast(cast(#an AS VARCHAR(4)) + '-'
+ cast(#MoisPaque AS VARCHAR(2)) + '-'
+ cast(#JourPaque AS VARCHAR(2)) AS DATETIME)
SET #LunPaque = DATEADD(DAY, 1, #DimPaque)
SET #JeuAscension = DATEADD(DAY, 39, #DimPaque)
SET #LunPentecote = DATEADD(DAY, 50, #DimPaque)
-- Jours fériés fixes
SET #NouvelAn = cast(cast(#an AS VARCHAR(4))+'-01-01 00:00:00' AS DATETIME)
SET #FeteTravail = cast(cast(#an AS VARCHAR(4))+'-05-01 00:00:00' AS DATETIME)
SET #Armistice3945 = cast(cast(#an AS VARCHAR(4))+'-05-08 00:00:00' AS DATETIME)
SET #Assomption = cast(cast(#an AS VARCHAR(4))+'-08-15 00:00:00' AS DATETIME)
SET #Armistice1418 = cast(cast(#an AS VARCHAR(4))+'-11-11 00:00:00' AS DATETIME)
SET #FeteNationale = cast(cast(#an AS VARCHAR(4))+'-07-14 00:00:00' AS DATETIME)
SET #ToussaINT = cast(cast(#an AS VARCHAR(4))+'-11-01 00:00:00' AS DATETIME)
SET #Noel = cast(cast(#an AS VARCHAR(4))+'-12-25 00:00:00' AS DATETIME)
INSERT INTO #JoursFeries (JourDate, JoURLabel)
SELECT #LunPaque, 'Lundi de Pâques'
UNION
SELECT #JeuAscension, 'Jeudi de l''Ascension'
UNION
SELECT #LunPentecote, 'Lundi de Pentecôte'
UNION
SELECT #NouvelAn, 'Nouvel an'
UNION
SELECT #FeteTravail, 'Fête du travail'
UNION
SELECT #Armistice3945, 'Armistice 39-45'
UNION
SELECT #Assomption, 'Assomption'
UNION
SELECT #FeteNationale, 'Fête Nationale'
UNION
SELECT #ToussaINT, 'Toussaint'
UNION
SELECT #Armistice1418, 'Armistice 14-18'
UNION
SELECT #Noel, 'Noël'
INSERT INTO #FERIES
SELECT * FROM #JoursFeries
RETURN
END
GO
CREATE FUNCTION FN_JOUR_TRAVAILLE (#Date1 DATETIME)
RETURNS INT AS
BEGIN
DECLARE #FLAG INT
SET #FLAG = 1
DECLARE #YEAR INT
SET #YEAR = DATEPART(YEAR, #DATE1)
IF EXISTS(SELECT * FROM FN_FERIES_SELON_ANNEE(#YEAR) WHERE JourDate = #Date1) BEGIN
SET #FLAG = 0
END
ELSE
IF DatePart(weekday, #DATE1) = 7 OR DatePart(weekday, #DATE1) = 1 BEGIN
SET #FLAG = 0
END
RETURN #FLAG
END
GO
CREATE FUNCTION FN_DATEDIFF_SELON_HORAIRES_ENTREPRISE2 (#Date1 DATETIME, #Date2 DATETIME)
RETURNS INT AS
BEGIN
DECLARE #NB_Jours INT
DECLARE #Cpt INT
DECLARE #Jours_Travailles INT
DECLARE #Date1_at_8_am DATETIME
DECLARE #Date2_at_6_pm DATETIME
DECLARE #Excedent INT
SET #NB_Jours = DATEDIFF(day, #Date1, #Date2) + 1
SET #Cpt = 0
SET #Jours_Travailles = 0
SET #Excedent = 0
SET #Date1_at_8_am = #Date1
SET #Date1_at_8_am = DATEADD(hour, - (DATEPART(hour, #Date1) - 8), #Date1_at_8_am)
SET #Date1_at_8_am = DATEADD(minute, - DATEPART(minute, #Date1_at_8_am), #Date1_at_8_am)
SET #Date1_at_8_am = DATEADD(second, - DATEPART(second, #Date1_at_8_am), #Date1_at_8_am)
SET #Date2_at_6_pm = #Date2
SET #Date2_at_6_pm = DATEADD(hour, 18 - DATEPART(hour, #Date2), #Date2_at_6_pm)
SET #Date2_at_6_pm = DATEADD(minute, - DATEPART(minute, #Date2_at_6_pm), #Date2_at_6_pm)
SET #Date2_at_6_pm = DATEADD(second, - DATEPART(second, #Date2_at_6_pm), #Date2_at_6_pm)
IF dbo.FN_JOUR_TRAVAILLE(#Date1) = 1 AND #Date1 > #Date1_at_8_am BEGIN
SET #Excedent = #Excedent + DATEDIFF(minute, #Date1_at_8_am, #Date1)
END
IF dbo.FN_JOUR_TRAVAILLE(#Date2) = 1 AND #Date2 < #Date2_at_6_pm BEGIN
SET #Excedent = #Excedent + DATEDIFF(minute, #Date2, #Date2_at_6_pm)
END
WHILE #Cpt < #NB_Jours
BEGIN
IF dbo.FN_JOUR_TRAVAILLE(DATEADD(day, #Cpt, #Date1)) = 1
BEGIN
SET #Jours_Travailles = #Jours_Travailles + 1
END
SET #Cpt = #Cpt + 1
END
RETURN #Jours_Travailles*600 - #Excedent
END
GO
-----------------------------------------------------------------------
-----------------------------------------------------------------------
-----------------------------------------------------------------------
The problem is in the function FN_JOUR_TRAVAILLE at this line:
IF EXISTS(SELECT * FROM FN_FERIES_SELON_ANNEE(#YEAR) WHERE JourDate = #Date1) BEGIN
SET #FLAG = 0
END
For each day of each period I calculate I generate the table of public holidays for the year.
The best solution would be to check if I did not already create this table, whether I search in it, if not I create it and I store it.
But I dont know how to do this.
I need to create a table in a superior scope and pass it as parameter in my functions I think.
How about a table type parameter:
create type FERIES as table (
JourId INT NOT NULL,
JourDate DATETIME NOT NULL,
JoURLabel VARCHAR(50) NULL
)
GO
In your outer scope use the FN_FERIES_SELON_ANNEE function to populate a table value:
declare #var FERIES;
insert into #var
select * from FN_FERIES_SELON_ANNEE(#YEAR)
and then pass it to your other function to use.
Your other function would become:
CREATE FUNCTION FN_JOUR_TRAVAILLE (#Date1 DATETIME, #table FERIES readonly)
RETURNS INT AS
BEGIN
DECLARE #FLAG INT
SET #FLAG = 1
DECLARE #YEAR INT
SET #YEAR = DATEPART(YEAR, #DATE1)
IF EXISTS(SELECT * FROM #table WHERE JourDate = #Date1) BEGIN
SET #FLAG = 0
END
ELSE
IF DatePart(weekday, #DATE1) = 7 OR DatePart(weekday, #DATE1) = 1 BEGIN
SET #FLAG = 0
END
RETURN #FLAG
END
GO
Try use XML -
DECLARE #XML XML
SELECT #XML = (
SELECT JourId, JourDate, JoURLabel
FROM #JoursFeries t
FOR XML AUTO
)
RETURN #XML
CREATE FUNCTION FN_JOUR_TRAVAILLE (#Date1 DATETIME, #XML XML)
RETURNS INT
AS BEGIN
DECLARE #YEAR INT
SELECT #YEAR = DATEPART(YEAR, #DATE1)
IF EXISTS(
SELECT 1
FROM #XML.nodes('/t') t(p)
WHERE t.p.value('#JourDate', 'DATETIME') = #Date1
) OR DATEPART(weekday, #DATE1) IN (1, 7)
BEGIN
RETURN 0
END
RETURN 1
END
UPDATE (2005 or higher):
Or try this solution -
ALTER FUNCTION FN_FERIES_SELON_ANNEE (#YEAR INT)
RETURNS XML
AS BEGIN
DECLARE
#an VARCHAR(4)
, #G INT, #I INT
, #J INT, #C INT
, #H INT, #L INT
, #JourPaque INT
, #MoisPaque INT
, #DimPaque DATETIME
SELECT #an = CAST(#YEAR AS VARCHAR(4))
SELECT
#G = #YEAR % 19
, #C = #YEAR / 100
, #H = (#C - #C / 4 - (8 * #C + 13) / 25 + 19 * #G + 15) % 30
, #I = #H - (#H / 28) * (1 - (#H / 28) * (29 / (#H + 1)) * ((21 - #G) / 11))
, #J = (#YEAR + #YEAR / 4 + #I + 2 - #C + #C / 4) % 7
, #L = #I - #J
, #MoisPaque = 3 + (#L + 40) / 44
, #JourPaque = #L + 28 - 31 * (#MoisPaque / 4)
, #DimPaque = CAST(#an + '-' + CAST(#MoisPaque AS VARCHAR(2)) + '-' + CAST(#JourPaque AS VARCHAR(2)) AS DATETIME)
DECLARE #XML XML
SELECT #XML = (
SELECT JourId, JourDate, JoURLabel
FROM (
SELECT JourId = 1, JourDate = DATEADD(DAY, 1, #DimPaque), JoURLabel = 'Lundi de Pâques'
UNION ALL
SELECT 2, DATEADD(DAY, 39, #DimPaque), 'Jeudi de l''Ascension'
UNION ALL
SELECT 3, DATEADD(DAY, 50, #DimPaque), 'Lundi de Pentecôte'
UNION ALL
SELECT 4, CAST(#an + '0101' AS DATETIME), 'Nouvel an'
UNION ALL
SELECT 5, CAST(#an + '0501' AS DATETIME), 'Fête du travail'
UNION ALL
SELECT 6, CAST(#an + '0508' AS DATETIME), 'Armistice 39-45'
UNION ALL
SELECT 7, CAST(#an + '0815' AS DATETIME), 'Assomption'
UNION ALL
SELECT 8, CAST(#an + '0714' AS DATETIME), 'Fête Nationale'
UNION ALL
SELECT 9, CAST(#an + '1101' AS DATETIME), 'Toussaint'
UNION ALL
SELECT 10, CAST(#an + '1111' AS DATETIME), 'Armistice 14-18'
UNION ALL
SELECT 11, CAST(#an + '1101' AS DATETIME), 'Noël'
) t
FOR XML AUTO
)
RETURN #XML
END
GO
ALTER FUNCTION FN_JOUR_TRAVAILLE (#Date1 DATETIME, #XML XML)
RETURNS INT
AS BEGIN
DECLARE #YEAR INT
SELECT #YEAR = DATEPART(YEAR, #DATE1)
IF EXISTS(
SELECT 1
FROM #XML.nodes('/t') t(p)
WHERE t.p.value('#JourDate', 'DATETIME') = #Date1
) OR DATEPART(weekday, #DATE1) IN (1, 7)
BEGIN
RETURN 0
END
RETURN 1
END
GO
ALTER FUNCTION FN_DATEDIFF_SELON_HORAIRES_ENTREPRISE2
(
#Date1 DATETIME
, #Date2 DATETIME
)
RETURNS INT AS
BEGIN
DECLARE
#NB_Jours INT
, #Cpt INT
, #Jours_Travailles INT
, #Date1_at_8_am DATETIME
, #Date2_at_6_pm DATETIME
, #Excedent INT
SELECT
#NB_Jours = DATEDIFF(DAY, #Date1, #Date2) + 1
, #Cpt = 0
, #Jours_Travailles = 0
, #Excedent = 0
, #Date1_at_8_am = DATEADD(HOUR, 8, CAST(FLOOR(CAST(#Date1 AS FLOAT)) AS DATETIME))
, #Date2_at_6_pm = DATEADD(HOUR, 18, CAST(FLOOR(CAST(#Date1 AS FLOAT)) AS DATETIME))
SELECT #Excedent = #Excedent +
CASE WHEN #Date1 > #Date1_at_8_am AND dbo.FN_JOUR_TRAVAILLE(#Date1, dbo.FN_FERIES_SELON_ANNEE(YEAR(#Date1))) = 1
THEN DATEDIFF(MINUTE, #Date1_at_8_am, #Date1)
ELSE 0
END +
CASE WHEN #Date2 < #Date2_at_6_pm AND dbo.FN_JOUR_TRAVAILLE(#Date2, dbo.FN_FERIES_SELON_ANNEE(YEAR(#Date2))) = 1
THEN DATEDIFF(MINUTE, #Date2, #Date2_at_6_pm)
ELSE 0
END
;WITH years AS
(
SELECT cont = 1, dt = DATEADD(DAY, #Cpt, #Date1), years = YEAR(DATEADD(DAY, #Cpt, #Date1))
UNION ALL
SELECT cont + 1, DATEADD(DAY, 1, dt), YEAR(DATEADD(DAY, 1, dt))
FROM years
WHERE cont < #NB_Jours
)
SELECT #Jours_Travailles = SUM(dbo.FN_JOUR_TRAVAILLE(dt, tt.xmls))
FROM years y
JOIN (
SELECT y3.years, xmls = dbo.FN_FERIES_SELON_ANNEE(y3.years)
FROM (
SELECT DISTINCT y2.years
FROM years y2
) y3
) tt ON tt.years = y.years
OPTION (MAXRECURSION 0)
RETURN #Jours_Travailles * 600 - #Excedent
END
UPDATE2 (2000):
There appear to be quite a big number of restrictions if using version 2000. Please try this example. I do not count it as a perfect decision to solve the problem without changing the current logic, but I think it should be helpful for you.
ALTER FUNCTION FN_FERIES_SELON_ANNEE (#YEAR INT)
RETURNS #FERIES TABLE
(
JourId INT NOT NULL
, JourDate DATETIME NOT NULL
, JoURLabel VARCHAR(50) NULL
)
AS BEGIN
DECLARE
#an VARCHAR(4)
, #G INT, #I INT
, #J INT, #C INT
, #H INT, #L INT
, #JourPaque INT
, #MoisPaque INT
, #DimPaque DATETIME
SELECT #an = CAST(#YEAR AS VARCHAR(4))
SELECT
#G = #YEAR % 19
, #C = #YEAR / 100
, #H = (#C - #C / 4 - (8 * #C + 13) / 25 + 19 * #G + 15) % 30
, #I = #H - (#H / 28) * (1 - (#H / 28) * (29 / (#H + 1)) * ((21 - #G) / 11))
, #J = (#YEAR + #YEAR / 4 + #I + 2 - #C + #C / 4) % 7
, #L = #I - #J
, #MoisPaque = 3 + (#L + 40) / 44
, #JourPaque = #L + 28 - 31 * (#MoisPaque / 4)
, #DimPaque = CAST(#an + '-' + CAST(#MoisPaque AS VARCHAR(2)) + '-' + CAST(#JourPaque AS VARCHAR(2)) AS DATETIME)
INSERT INTO #FERIES (JourId, JourDate, JoURLabel )
SELECT JourId, JourDate, JoURLabel
FROM (
SELECT JourId = 1, JourDate = DATEADD(DAY, 1, #DimPaque), JoURLabel = 'Lundi de Pâques'
UNION ALL
SELECT 2, DATEADD(DAY, 39, #DimPaque), 'Jeudi de l''Ascension'
UNION ALL
SELECT 3, DATEADD(DAY, 50, #DimPaque), 'Lundi de Pentecôte'
UNION ALL
SELECT 4, CAST(#an + '0101' AS DATETIME), 'Nouvel an'
UNION ALL
SELECT 5, CAST(#an + '0501' AS DATETIME), 'Fête du travail'
UNION ALL
SELECT 6, CAST(#an + '0508' AS DATETIME), 'Armistice 39-45'
UNION ALL
SELECT 7, CAST(#an + '0815' AS DATETIME), 'Assomption'
UNION ALL
SELECT 8, CAST(#an + '0714' AS DATETIME), 'Fête Nationale'
UNION ALL
SELECT 9, CAST(#an + '1101' AS DATETIME), 'Toussaint'
UNION ALL
SELECT 10, CAST(#an + '1111' AS DATETIME), 'Armistice 14-18'
UNION ALL
SELECT 11, CAST(#an + '1101' AS DATETIME), 'Noël'
) t
RETURN
END
GO
ALTER FUNCTION FN_DATEDIFF_SELON_HORAIRES_ENTREPRISE2
(
#Date1 DATETIME
, #Date2 DATETIME
)
RETURNS INT AS
BEGIN
DECLARE
#NB_Jours INT
, #Year INT
, #Jours_Travailles INT
, #Date1_at_8_am DATETIME
, #Date2_at_6_pm DATETIME
, #Excedent INT
SELECT
#NB_Jours = DATEDIFF(DAY, #Date1, #Date2) + 1
, #Jours_Travailles = 0
, #Excedent = 0
, #Date1_at_8_am = DATEADD(HOUR, 8, CAST(FLOOR(CAST(#Date1 AS FLOAT)) AS DATETIME))
, #Date2_at_6_pm = DATEADD(HOUR, 18, CAST(FLOOR(CAST(#Date1 AS FLOAT)) AS DATETIME))
DECLARE #emun TABLE (i BIGINT IDENTITY, blank BIT )
INSERT INTO #emun (blank)
SELECT NULL
FROM [master].dbo.spt_values n
CROSS JOIN (
SELECT i = 1
UNION ALL
SELECT 2
UNION ALL
SELECT 3
) b
DECLARE #temp TABLE (dt DATETIME)
INSERT INTO #temp (dt)
SELECT dt
FROM (
SELECT dt = #Date1
UNION ALL
SELECT DATEADD(DAY, i, #Date1)
FROM #emun
WHERE i < #NB_Jours
) d
DECLARE #temp2 TABLE
(
JourId INT NOT NULL
, JourDate DATETIME NOT NULL
, JoURLabel VARCHAR(50) NULL
)
DECLARE cur CURSOR FAST_FORWARD READ_ONLY LOCAL FOR
SELECT DISTINCT YEAR(y.dt)
FROM #temp y
OPEN cur
FETCH NEXT FROM cur INTO #Year
WHILE ##FETCH_STATUS = 0 BEGIN
INSERT INTO #temp2 (JourId, JourDate, JoURLabel)
SELECT JourId, JourDate, JoURLabel
FROM FN_FERIES_SELON_ANNEE(#Year)
FETCH NEXT FROM cur INTO #Year
END
CLOSE cur
DEALLOCATE cur
SELECT #Excedent = #Excedent +
CASE WHEN #Date1 > #Date1_at_8_am AND NOT EXISTS(SELECT 1 FROM #temp2 WHERE JourDate = #Date1 OR DATEPART(weekday, #Date1) IN (1,7))
THEN DATEDIFF(MINUTE, #Date1_at_8_am, #Date1)
ELSE 0
END +
CASE WHEN #Date2 < #Date2_at_6_pm AND NOT EXISTS(SELECT 1 FROM #temp2 WHERE JourDate = #Date2 OR DATEPART(weekday, #Date2) IN (1,7))
THEN DATEDIFF(MINUTE, #Date2, #Date2_at_6_pm)
ELSE 0
END
SELECT #Jours_Travailles = COUNT(1)
FROM #temp t
LEFT JOIN #temp2 t2 ON t.dt = t2.JourDate
WHERE NOT(t2.JourId IS NOT NULL OR DATEPART(weekday, t.dt) IN (1,7))
RETURN #Jours_Travailles * 600 - #Excedent
END
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