我在桌子上有一个学校的时间表。我也知道学校的startDate和endDate。表结构如下:
SubjectsToDay
Subject | Day
---------------------
Maths | Monday
Physics | Tuesday
Chemistry| Wednesday
Maths | Thursday
Biology | Friday
假日
Date | Reason
----------------------------
2014-01-26 | Republic day
2014-05-01 | Labour's day
2014-06-04 | Reason1
2014-07-04 | Reason2
2014-07-14 | Reason3
2014-08-14 | Reason4
2014-09-14 | Reason5
2014-10-12 | Reason6
我想计算一个特定主题的工作天数(输入,比方说数学)。
工作日不应考虑Holidays
表中给出的假期。我想在存储过程中执行此操作,该过程以StartDate,EndDate和Subject作为参数。我怎样才能有效地纠正这个问题?
P.S.-假期表不固定,可以在此
中添加或删除任何行答案 0 :(得分:1)
使用cte获取所有日期,加入主题以计算课程数量并加入假期以排除它们:
declare @startdate date;
set @startdate = '2014-01-01';
declare @enddate date;
set @enddate = '2014-12-31'
;with DateRange AS
(
SELECT
@startdate as DateValue
UNION ALL
SELECT
dateadd(dd,1,DateValue)
FROM DateRange
WHERE dateadd(dd,1,DateValue) <= @enddate
)
select
s.Name
, COUNT(*)
from DateRange d
join SubjectsToDay s
on DATENAME(dw,d.DateValue) = s.Day
left outer join
Holidays h
on d.DateValue = h.Date
where h.Reason is null
group by
s.Name
option (maxrecursion 365)
答案 1 :(得分:0)
大多数人会为此使用日历表,但这里的计算应该给出相同的结果。我建议你把它与你的环境合并后把它放到存储过程中。
-- your parameters
DECLARE @from date = '2014-01-01', @to date = '2014-01-01'
DECLARE @Subjectname varchar(15) = 'Chemistry'
-- variable declarations
DECLARE @d int
DECLARE @holiday TABLE(Date date, Reason varchar(20))
DECLARE @subject TABLE(Name varchar(15), Day varchar(10))
-- mapping day to numeric value
;WITH x as
(
SELECT CASE Day WHEN 'Monday' THEN 2
WHEN 'Tuesday' THEN 3
WHEN 'Wednesday' THEN 4
WHEN 'Thursday' THEN 5
WHEN 'Friday' THEN 6
-- allowing weekends for solving similar questions
WHEN 'Saturday' THEN 7
WHEN 'Sunday' THEN 1 END daynumber
FROM SubjectsToDay
WHERE Subject = @Subjectname
)
SELECT
-- number of chosen days between from and to
-- subtract holidays from same day between from and to
SUM(datediff(week, dateadd(d, -daynumber, @from),
dateadd(d, 1-daynumber, @to))
-y.cnt)
FROM X
CROSS APPLY
( SELECT count(*) cnt FROM Holidays WHERE datediff(d, -1, Date ) %7 + 1 = daynumber
AND Date between @from and @to) y