你可以得到所有工作日第一次約會後,再申請ROW_NUMBER()
得到的天數爲每個日期:
SELECT Date, DayNum = ROW_NUMBER() OVER(ORDER BY Date)
FROM Calendar
WHERE IsWorkingDay = 1
AND Date >= @StartPlanned
然後,它也只是對第6天過濾的情況下:
DECLARE @StartPlanned DATE = '20160502',
@Days INT = 6;
SELECT Date
FROM ( SELECT Date, DayNum = ROW_NUMBER() OVER(ORDER BY Date)
FROM Calendar
WHERE WorkingDay = 1
AND Date >= @StartPlanned
) AS c
WHERE c.DayNum = @Days;
這不是問題的一部分,但對於未來的打樣,這是更容易在SQL Server 2012+到acheive與OFFSET/FETCH
DECLARE @StartPlanned DATE = '20160502',
@Days INT = 6;
SELECT Date
FROM dbo.Calendar
WHERE Date >= @StartPlanned
AND WorkingDay = 1
ORDER BY Date
OFFSET (@Days - 1) ROWS FETCH NEXT 1 ROWS ONLY
附錄
我錯過了早前部分關於有另一個表中,關於把它變成一個遊標的評論促使我修改我的答案。我想補充一個新的列到你叫WorkingDayRank
年曆表:
ALTER TABLE dbo.Calendar ADD WorkingDayRank INT NULL;
GO
UPDATE c
SET WorkingDayRank = wdr
FROM ( SELECT Date, wdr = ROW_NUMBER() OVER(ORDER BY Date)
FROM dbo.Calendar
WHERE WorkingDay = 1
) AS c;
這可以即時完成,但它存儲爲一個值,你會得到更好的性能,那麼您的查詢就會變成:
SELECT p.Name,
p.Start_Planned,
p.Work_days_Required,
EndDate = c2.Date
FROM Projects AS P
INNER JOIN dbo.Calendar AS c1
ON c1.Date = p.Start_Planned
INNER JOIN dbo.Calendar AS c2
ON c2.WorkingDayRank = c1.WorkingDayRank + p.Work_days_Required - 1;
這只是獲取你的起始日期的工作日排名,並找到未來該項目通過連接在WorkingDayRank
指定的天數(-1,因爲你想要的結束日期以下的範圍內的)
這將失敗,如果你e版本計劃雖然開始在非工作日項目,讓一個更強大的解決方案可能是:
SELECT p.Name,
p.Start_Planned,
p.Work_days_Required,
EndDate = c2.Date
FROM Projects AS P
CROSS APPLY
( SELECT TOP 1 c1.Date, c1.WorkingDayRank
FROM dbo.Calendar AS c1
WHERE c1.Date >= p.Start_Planned
AND c1.WorkingDay = 1
ORDER BY c1.Date
) AS c1
INNER JOIN dbo.Calendar AS c2
ON c2.WorkingDayRank = c1.WorkingDayRank + p.Work_days_Required - 1;
這使用CROSS APPLY
得到或您的項目開始日期後的下一個工作日,則適用相同的連接像之前一樣。
不Projects.Start_Planned具有1:1的與Calendar.Day關係?平日專欄是必要的嗎? – qxg