簡體   English   中英

查找每月sql的第一個和最后一個工作日

[英]Finding the first and last business day for every month sql

我正在嘗試查找自1986年以來每個月的第一個和最后一個工作日。使用它,我可以找到任何給定月份的第一天,但​​僅使用該月,並且它沒有考慮是工作日還是工作日。不。 為了方便起見,工作日只是工作日,不考慮公眾假期。

SELECT DATEADD(s,0,DATEADD(mm, DATEDIFF(m,0,getdate()),0))

但是我無法獲得正確的工作日,因此我創建了一個包含所有工作日的日歷表,並認為我可以從每個月中提取分鍾(日期),但目前我陷入了困境。

Date
---------------
1986-01-01
1986-01-02
1986-01-03
1986-01-06
...and so on

我嘗試獲取每個月的第一天,但​​是沒有考慮到這一天是否是周末。 只是簡單地給出每個月的第一天

declare @DatFirst date = '20000101', @DatLast date = getdate();
declare @DatFirstOfFirstMonth date = dateadd(day,1-day(@DatFirst),@DatFirst);
select  DatFirstOfMonth = dateadd(month,n,@DatFirstOfFirstMonth)
from    (select  top (datediff(month,@DatFirstOfFirstMonth,@DatLast)+1)
            n=row_number() over (order by (select 1))-1
    from    (values (1),(1),(1),(1),(1),(1),(1),(1)) a (n)
    cross join (values (1),(1),(1),(1),(1),(1),(1),(1)) b (n)
    cross join (values (1),(1),(1),(1),(1),(1),(1),(1)) c (n)
    cross join (values (1),(1),(1),(1),(1),(1),(1),(1)) d (n)
    ) x

我想知道是否有人可以闡明如何最好地解決這個問題。

如果您已經擁有帶有所有可用日期的日歷表,則只需要按工作日進行過濾即可。

SET DATEFIRST 1 -- 1: Monday, 7: Sunday

SELECT
    Year = YEAR(T.Date),
    Month = MONTH(T.Date),
    FirstBusinessDay = MIN(T.Date),
    LastBusinessDay = MAX(T.Date)
FROM
    Calendar AS T
WHERE
    DATEPART(WEEKDAY, T.Date) BETWEEN 1 AND 5 -- 1: Monday, 5: Friday
GROUP BY
    YEAR(T.Date),
    MONTH(T.Date)

您應該使用查詢在日歷表上標記這些天,因此以后很容易訪問它們。


這樣可以將其與日歷表的生成(帶有遞歸)混合使用。

SET DATEFIRST 1 -- 1: Monday, 7: Sunday

declare 
    @DatFirst date = '20000101', 
    @DatLast date = getdate();

;WITH AllDays AS
(
    SELECT
        Date = @DatFirst

    UNION ALL

    SELECT
        Date = DATEADD(DAY, 1, D.Date)
    FROM
        AllDays AS D
    WHERE
        D.Date < @DatLast
),
BusinessLimitsByMonth AS
(
    SELECT
        Year = YEAR(T.Date),
        Month = MONTH(T.Date),
        FirstBusinessDay = MIN(T.Date),
        LastBusinessDay = MAX(T.Date)
    FROM
        AllDays AS T
    WHERE
        DATEPART(WEEKDAY, T.Date) BETWEEN 1 AND 5 -- 1: Monday, 5: Friday
    GROUP BY
        YEAR(T.Date),
        MONTH(T.Date)
)
SELECT
    *
FROM
    BusinessLimitsByMonth AS B
ORDER BY
    B.Year,
    B.Month
OPTION
    (MAXRECURSION 0) -- 0: Unlimited

如果您已經有了一個只包含所有工作日的表格:

select min(datecol), max(datecol)
from BusinessOnlyCalendar
group by year(datecol), month(datecol)

但是您應該擴展日歷,以包括您可能在日期進行的所有這些計算,例如FirstDayOfWeek / Month / Quarter / Year,WeekNumber等。

當您在日歷中看到一列指示工作日yes / no時 ,這很簡單:

select min(datecol), max(datecol)
from calendar
where businessday = 'y'
group by year(datecol), month(datecol)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM