Web design and hosting, database, cloud and social media solutions that deliver business results
  • 商务解决方案
  • 数据库咨询服务
    • 报告
      • Claytabase Server Disk IOPs Calculator
      • SQL代码备份
      • SQL打印机
    • 技术文章
      • SQL-Server
      • SQL Server 2008的维护计划
      • 使用SQL Server函数
      • 使用SQL Server日期
      • 使用SQL Server透视-取消透视
  • 网站设计
    • 怀特岛
    • 技术文章
      • ASP-NET
      • CSS
    • 网站安全
  • 产品展示
  • 社交媒体
  • 关于我们
    • 投资组合
    • 球队
      • 切斯特Copperpot
  • 学院
عربى (AR)čeština (CS)Deutsch (DE)English (EN-US)English (EN-GB)Español (ES)فارسی (FA)Français (FR)हिंदी (HI)italiano (IT)日本語 (JA)polski (PL)Português (PT)русский (RU)Türk (TR)中国的 (ZH)

使用灵活的选项计算SQL Server函数中一个月中的天数

灵活且可重复使用的SQL Server函数,可以计算一个月中的天数,并可以选择不包括假期或周末

如果您已签出其他文章,则可能已经有了该表,如果没有,请使用下面的代码来创建它。这些基于英格兰和威尔士的标准假期。主页上提供其他国家的功能。

CREATE TABLE Dates.Calendar(
CalendarDate DATETIME2 NOT NULL CONSTRAINT PK_CalendarDate PRIMARY KEY,
CalendarCA AS (DATEDIFF(DAY,DATEADD(DAY,1-DATEPART(DAY,CalendarDate),CalendarDate),CalendarDate)/7)+1 PERSISTED,
CalendarCD AS (DATEDIFF(DAY,CalendarDate,DATEADD(DAY,-1,DATEADD(MONTH,1,DATEADD(DAY,1-DATEPART(DAY,CalendarDate),CalendarDate))))/7)+1 PERSISTED,
WeekDayID AS (DATEPART(weekday,[CalendarDate])),
WeekDayName AS (case DATEPART(weekday,[CalendarDate]) when (1) then 'Sunday' when (2) then 'Monday' when (3) then 'Tuesday' when (4) then 'Wednesday' when (5) then 'Thursday' when (6) then 'Friday' when (7) then 'Saturday'  end))
GO
DECLARE @D DATETIME2='1850-01-01'
WHILE @D<='2099-12-31' BEGIN
INSERT INTO Dates.Calendar(CalendarDate) SELECT @D
SET @D=DATEADD(DAY,1,@D)
END
GO
CREATE TABLE Dates.CalendarHolidays(CalendarDate DATETIME2 NOT NULL,CalendarFunction INT NOT NULL,HolidayType VARCHAR(100) NULL,CONSTRAINT PK_Holidays_Id PRIMARY KEY(CalendarDate,CalendarFunction))
GO
/*English & Welsh Holidays*/
INSERT INTO Dates.CalendarHolidays
SELECT CalendarDate,0,'New Years Day' FROM Dates.Calendar WHERE DATEPART(MONTH,CalendarDate)=1 AND DATEPART(DAY,CalendarDate)=1 UNION --New Years Day
SELECT CalendarDate,0,'Good Friday' FROM Dates.Calendar WHERE CalendarDate=DATEADD(DAY,-2,Dates.GetEasterDate(DATEPART(YEAR,CalendarDate))) UNION--Good Friday
SELECT CalendarDate,0,'Easter Monday' FROM Dates.Calendar WHERE CalendarDate=DATEADD(DAY,1,Dates.GetEasterDate(DATEPART(YEAR,CalendarDate))) UNION--Easter Monday
SELECT CalendarDate,0,'May Holidays' FROM Dates.Calendar WHERE DATEPART(MONTH,CalendarDate)=5 AND WeekDayID=2 AND (CalendarCA=1 OR CalendarCD=1)UNION--May Holidays
SELECT CalendarDate,0,'August Holidays' FROM Dates.Calendar WHERE DATEPART(MONTH,CalendarDate)=8 AND WeekDayID=2 AND (CalendarCD=1) UNION--August Holidays
SELECT CalendarDate,0,'Christmas Day' FROM Dates.Calendar WHERE DATEPART(MONTH,CalendarDate)=12 AND DATEPART(DAY,CalendarDate)=25 UNION --Christmas Day
SELECT CalendarDate,0,'Boxing Day' FROM Dates.Calendar WHERE DATEPART(MONTH,CalendarDate)=12 AND DATEPART(DAY,CalendarDate)=26 --Boxing Day
GO

现在我们有了数据,我们可以创建一个函数,该函数取决于一些变量,从月初到月底循环遍历每一天:

  • @Month-输入任何日期,系统将为该月进行计算。
  • @CalendarFunction-您要使用的假期功能。
  • @AdjustMode-包含天或排除天,应标准设置为1,但使用0可以休假,以便与其他功能结合使用(例如添加天数)。
  • @AdjustWeekends-从计算中排除周末
  • @AdjustHolidays-如果假期功能匹配,则排除假期

CREATE FUNCTION Dates.GetMonthAdjusted(@Month As DATETIME2,@CalendarFunction INT,@AdjustMode BIT,@AdjustWeekEnds BIT,@AdjustHolidays BIT)
RETURNS INT AS BEGIN
DECLARE @StartDate DATETIME2=CONVERT(DATE,DATEADD(DAY,1-DAY(@Month),@Month))
DECLARE @EndDate DATETIME2=DATEADD(DAY,-1,DATEADD(MONTH,1,@StartDate)),@Count AS INT=0,@Date As DATETIME2=@StartDate
WHILE @Date < @EndDate
BEGIN
IF ((DATEPART(WEEKDAY,@Date) IN(1,7) AND @AdjustWeekEnds=1)
OR
EXISTS (SELECT * FROM Dates.CalendarHolidays WHERE CalendarDate=@Date AND CalendarFunction=@CalendarFunction AND @AdjustHolidays=1))
BEGIN
 SELECT @Count = @Count + 1
END
SET @Date=DATEADD(DAY, 1,@Date)
END
RETURN (DATEDIFF(DAY,@StartDate,@EndDate)-(@Count))+@AdjustMode
END
SELECT Dates.GetMonthAdjusted('2014-01-01',0,1,1,1) --22
SELECT Dates.GetMonthAdjusted('2014-01-01',0,1,1,0) --23
SELECT Dates.GetMonthAdjusted('2014-01-01',0,1,0,1) --30
SELECT Dates.GetMonthAdjusted('2014-01-01',0,1,0,0) --31
SELECT Dates.GetMonthAdjusted('2014-02-04',0,1,1,1) --20
SELECT Dates.GetMonthAdjusted('2014-05-15',0,1,1,1) --20 (22-2)

Author

Was this helpful?

Please note, this commenting system is still in final testing.
Copyright Claytabase Ltd 2020

Registered in England and Wales 08985867

RSSLoginLink Cookie政策网站地图

Social Media

facebook.com/Claytabaseinstagram.com/claytabase/twitter.com/Claytabaselinkedin.com/company/claytabase-ltd

Get in Touch

+442392064871info@claytabase.comClaytabase Ltd, Unit 3d, Rink Road Industrial Estate, PO33 2LT, United Kingdom
此网站上的设置设置为允许所有Cookie。 这些可以在我们的Cookie政策和设置页面上更改。继续使用本网站即表示您同意使用Cookie。
Ousia Logo
Logout
Ousia CMS Loader