简体   繁体   English

在 SQL Server 中获取工作日

[英]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/012018/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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM