[英]Get working days in SQL Server
I have posted this problem ago but I guess I wasn't able to be as clear as I should have.我之前已经发布过这个问题,但我想我没有像我应该的那样清楚。 I want to calculate difference between 2 dates let's say 2018/01/01
and 2018/01/31
.我想计算两个日期之间的差异,比如说2018/01/01
和2018/01/31
。
I have a table Calendar
which is storing what day is a holiday and what is not.我有一个表Calendar
,它存储哪一天是假期,什么不是。 I am marking Sunday and Saturday as holidays, and want to calculate the working days remaining which should be 23.我将周日和周六标记为假期,并想计算剩余的工作日应该是 23。
But what actually the problem is that I can also mark Sunday as holiday and not Saturday.但实际上问题是我也可以将星期日标记为假期而不是星期六。
That's why I want to use this table as well.这就是为什么我也想使用这张表。 I see so many solutions that are giving me 23 result because they are marking Sunday and Saturday as holiday which is fine too but I want it to be using this table as well.我看到很多解决方案给了我 23 个结果,因为他们将周日和周六标记为假期,这也很好,但我也希望它使用这张表。
I tried much but I'm sure where I am going wrong.我尝试了很多,但我确定我哪里出错了。 Maybe somebody can help now.也许现在有人可以帮忙。
Table is like this表是这样的
CREATE TABLE Calendar
(
Day Varchar(25), --name of the day i.e Sunday, Saturday
IsOffDay Binary --1 for Yes and 0 for False
)
So if I mark Saturday and Sunday as holiday the result should be 23 days but if I only mark Sunday as holiday and make Saturday inactive then it should be 27 days因此,如果我将周六和周日标记为假期,结果应该是 23 天,但如果我只将周日标记为假期并使周六不活动,那么结果应该是 27 天
The proposed solution that one mate says is possible duplicate is getting Saturday and Sunday as holiday but I don't want that to be hard coded or whatever you say.一位伙伴说可能重复的提议解决方案是将周六和周日作为假期,但我不希望将其硬编码或您说的任何内容。
Try with this query .试试这个查询。
Your Table :你的表:
CREATE TABLE #Calendar
([Day] Varchar(25), --name of the day i.e Sunday, Saturday
IsOffDay BIT --1 for Yes and 0 for False
)
INSERT INTO #Calendar ([Day],IsOffDay)
SELECT 'Sunday',1 union
SELECT 'Saturday',0
Query询问
DECLARE @STARTDATE DATE='2018-01-01',@ENDDATE DATE='2018-01-31'
;WITH CTE AS (
SELECT @STARTDATE AS STARTDATE
UNION ALL
select DATEADD(D,1,STARTDATE)
FROM CTE
WHERE STARTDATE <@ENDDATE
)
,WORKINGDAYS AS (
SELECT STARTDATE,DATENAME(DW,STARTDATE)WEEKDAYS,C1.Day AS isweekend
FROM CTE c
left JOIN #Calendar C1 ON DATENAME(DW,STARTDATE)=C1.Day AND C1.IsOffDay=1
)
SELECT COUNT(WEEKDAYS)as WORKINGDAYS FROM WORKINGDAYS WHERE isweekend is null
Note: The above query gives you Working Days =27
.If you want saturday as holiday Update Calendar table IsOffDay=1 where [Day]='Saturday'
then gives you Working Days =23
注意:上面的查询给你Working Days =27
。如果你想星期六作为假期更新日历表IsOffDay=1 where [Day]='Saturday'
然后给你Working Days =23
Is this helpfull.?这有帮助吗。?
CREATE TABLE #Calendar
(
[Day] Varchar(25), --name of the day i.e Sunday, Saturday
IsOffDay BIT --1 for Yes and 0 for False
)
INSERT INTO #Calendar ([Day],IsOffDay)
SELECT 'Sunday',1
union
SELECT 'Saturday',0
--SElect * from #Calendar
DECLARE @StartDate DATETIME='01/01/2018'
DECLARE @EndDate DATETIME='01/31/2018'
SELECT TOP (DATEDIFF(DAY, @StartDate, @EndDate) + 1)
DATENAME(dw,DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, @StartDate)) as [Day]
INTO #tmpDays
FROM sys.all_objects a
CROSS JOIN sys.all_objects b;
--SELECT * FROM #tmpDays
SELECT COUnt(*) as WorkingDays
FROM #tmpDays t
LEFT JOIN #Calendar c on t.day=c.Day
WHERE (c.Day IS NULL)
OR
(c.IsOffDay =0)
Drop Table #Calendar
drop table #tmpDays
GEneral approach would be to make a calendar table that lists all the days for few years and marks them as holidays under certain law areas - you know it won't be big table as for a 10y period it's under 4000 rows.一般的方法是制作一个日历表,列出几年的所有日子,并将它们标记为某些法律领域下的假期 - 你知道它不会是大表,因为它在 4000 行以下的 10 年期间不会。 In this case you have very flexible solution that will handle not only weekends but also holidays, ad-hoc holidays like - I don't know - day of mourning or whatever, Easter etc.在这种情况下,您有非常灵活的解决方案,不仅可以处理周末,还可以处理假期,临时假期,例如 - 我不知道 - 哀悼日或其他什么,复活节等。
But if your heart is set on omitting certain weekdays then -但是,如果您决定省略某些工作日,那么-
CREATE TABLE Calendar (
DayOfWeek tinyint, --name of the day i.e 7 for Sunday, 6 for Saturday, 1 for Monday
IsOffDay Binary --1 for Yes and 0 for False
)
insert into Calendar (DayOfWeek, IsOffDay) values (7,1),(6,1)
And query:并查询:
set datefirst 1
declare @startDate date = '2018-01-01', @endDate date = '2018-01-31'
;
with numberOfDays as (
select datediff(day, @startDate, @endDate) + 1 /*including start end end*/ as days
),
numberOfHolidays as (
select FLOOR(days/7) + case when DayOfWeek between datepart(dw, @startDate) and datepart(dw, @endDate) or DayOfWeek between datepart(dw, @endDate) and datepart(dw, @startDate) then 1 else 0 end as holidays
from numberOfDays, Calendar
where IsOffDay = 1
),
aggregatedHolidays as (
select sum(holidays) as holidays from numberOfHolidays
)
select days - holidays
from numberOfDays, aggregatedHolidays
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.