Count of weekdays in a given month

我的未来我决定 提交于 2021-02-08 09:57:33

问题


I was facing a problem on how to create a calculated column based on a column which contains dates. For example, I have a column which contains dates starting from July.

The DAY needs to be calculated as described in the picture using SQL server.

So basically can a column be created based on an existing column containing a lot of dates? I need this to be dynamic.

WeekDay     Date        Day
---------------------------
Friday      3-Jan-14    1
Monday      6-Jan-14    2
Tuesday     7-Jan-14    3
Wednesday   8-Jan-14    4
Thursday    9-Jan-14    5
Friday      10-Jan-14   6
Monday      13-Jan-14   7
Tuesday     14-Jan-14   8
Wednesday   15-Jan-14   9
Thursday    16-Jan-14   10
Friday      17-Jan-14   11
Monday      20-Jan-14   12
Tuesday     21-Jan-14   13
Wednesday   22-Jan-14   14
Thursday    23-Jan-14   15
Friday      24-Jan-14   16
Monday      27-Jan-14   17
Tuesday     28-Jan-14   18
Wednesday   29-Jan-14   19
Thursday    30-Jan-14   20
Friday      31-Jan-14   21

回答1:


With table, DateTable with a column Date of type Date, the following query will do what you ask.

SELECT
    DATENAME(dw, Date) AS WeekDay
    ,Date
    ,ROW_NUMBER() OVER (ORDER BY Date) AS Day
FROM DateTable
WHERE DATEPART(dw, Date) NOT IN (1, 7)
ORDER BY Date



回答2:


Based on the Title and subject, I am guessing that you want to try and identify the working day number of each month.

example:

1-Jan-14 is Wednesday so its Working day number 1

6-Jan-14 is Monday so its working day number 4 as (4-Jan-14 and 5-Jan-14 are Weekends)

Also the result should be a derived column in a table that already has data.

If the above is true then this is what I suggest

  • Create a function to calculate the working days between two dates. (I have taken the last day of each oath as my initial date but you could also do +1 in you decide to go with first day of month way. (Personal preference really))
  • Alter table and add calculated column that calls the function

Sample Query:

IF OBJECT_ID('test') > 0
    BEGIN
        DROP TABLE test
    END;
GO

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ufn_WordkindDayNumber]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [dbo].ufn_WordkindDayNumber
GO

CREATE FUNCTION ufn_WordkindDayNumber(@Date DATETIME)
RETURNS INT
AS
BEGIN

DECLARE @LastDayofPreviousMonth DATETIME,
@Return int

SET @LastDayofPreviousMonth = CAST(YEAR(@Date) as VARCHAR(4))+RIGHT('00'+CAST(MONTH(@Date) as VARCHAR(2)),2)+'01'
SET @LastDayofPreviousMonth = DATEADD (day, -1, CAST(@LastDayofPreviousMonth AS DATE))

-- Logic addapted from http://stackoverflow.com/questions/252519/count-work-days-between-two-dates. Credit CMS
SELECT @Return =
    CASE 
            WHEN DATENAME(dw, @Date) = 'Sunday' OR DATENAME(dw, @Date) = 'Saturday' THEN 0
            ELSE
               (DATEDIFF(dd, @LastDayofPreviousMonth, @Date))
              -(DATEDIFF(wk, @LastDayofPreviousMonth, @Date) * 2)
              -(CASE WHEN DATENAME(dw, @Date) IN ('Saturday', 'Sunday') THEN 1 ELSE 0 END)
            END

    -- Return the result of the function
    RETURN @Return
END

GO

CREATE TABLE test ([date] DATE NULL);

INSERT INTO test
SELECT '27-Dec-13' UNION ALL
SELECT '28-Dec-13' UNION ALL
SELECT '29-Dec-13'

ALTER TABLE test
ADD WordkindDayNumber AS dbo.ufn_WordkindDayNumber(Date);

GO

INSERT INTO test
SELECT '30-Dec-13' UNION ALL
SELECT '31-Dec-13' 

SELECT *
FROM test;

DROP TABLE test;

Validation Script:

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ufn_WordkindDayNumber]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [dbo].ufn_WordkindDayNumber
GO

CREATE FUNCTION ufn_WordkindDayNumber(@Date DATETIME)
RETURNS INT
AS
BEGIN

DECLARE @LastDayofPreviousMonth DATETIME,
@Return int

SET @LastDayofPreviousMonth = CAST(YEAR(@Date) as VARCHAR(4))+RIGHT('00'+CAST(MONTH(@Date) as VARCHAR(2)),2)+'01'
SET @LastDayofPreviousMonth = DATEADD (day, -1, CAST(@LastDayofPreviousMonth AS DATE))

-- Logic addapted from http://stackoverflow.com/questions/252519/count-work-days-between-two-dates. Credit CMS
SELECT @Return =
    CASE 
            WHEN DATENAME(dw, @Date) = 'Sunday' OR DATENAME(dw, @Date) = 'Saturday' THEN 0
            ELSE
               (DATEDIFF(dd, @LastDayofPreviousMonth, @Date))
              -(DATEDIFF(wk, @LastDayofPreviousMonth, @Date) * 2)
              -(CASE WHEN DATENAME(dw, @Date) IN ('Saturday', 'Sunday') THEN 1 ELSE 0 END)
            END

    -- Return the result of the function
    RETURN @Return
END

GO

;WITH cte_TestData(Date) AS
(SELECT '30-Dec-13' UNION ALL
SELECT '31-Dec-13' UNION ALL
SELECT '1-Jan-14' UNION ALL
SELECT '2-Jan-14' UNION ALL
SELECT '3-Jan-14' UNION ALL
SELECT '4-Jan-14' UNION ALL
SELECT '5-Jan-14' UNION ALL
SELECT '6-Jan-14' UNION ALL
SELECT '7-Jan-14' UNION ALL
SELECT '8-Jan-14' UNION ALL
SELECT '9-Jan-14' UNION ALL
SELECT '10-Jan-14' UNION ALL
SELECT '11-Jan-14' UNION ALL
SELECT '12-Jan-14' UNION ALL
SELECT '13-Jan-14' UNION ALL
SELECT '14-Jan-14' UNION ALL
SELECT '15-Jan-14' UNION ALL
SELECT '16-Jan-14' UNION ALL
SELECT '17-Jan-14' UNION ALL
SELECT '18-Jan-14' UNION ALL
SELECT '19-Jan-14' UNION ALL
SELECT '20-Jan-14' UNION ALL
SELECT '21-Jan-14' UNION ALL
SELECT '22-Jan-14' UNION ALL
SELECT '23-Jan-14' UNION ALL
SELECT '24-Jan-14' UNION ALL
SELECT '25-Jan-14' UNION ALL
SELECT '26-Jan-14' UNION ALL
SELECT '27-Jan-14' UNION ALL
SELECT '28-Jan-14' UNION ALL
SELECT '29-Jan-14' UNION ALL
SELECT '30-Jan-14' UNION ALL
SELECT '31-Jan-14' )
,cte_FirstDateofMonth as
(
SELECT Date, 
        CAST(YEAR(DATE) as VARCHAR(4))+RIGHT('00'+CAST(MONTH(DATE) as VARCHAR(2)),2)+'01' AS FDoM
FROM cte_TestData
)
,cte_LastDayofPreviousMonth as
(
SELECT Date, 
        DATEADD (day, -1, CAST(FDoM AS DATE)) as LDoPM
FROM cte_FirstDateofMonth
)
SELECT  [Date],
        DATENAME(dw, Date) AS DatofWeek,
        CASE 
            WHEN DATENAME(dw, Date) = 'Sunday' OR DATENAME(dw, Date) = 'Saturday' THEN 0
            ELSE
            DATEDIFF(dd, LDoPM, Date) 
            - (DATEDIFF(wk, LDoPM, Date) * 2) 
            - (CASE
                  WHEN DATENAME(dw, Date) = 'Sunday' OR DATENAME(dw, Date) = 'Saturday' THEN 1
                  ELSE 0
              END) 
        END AS WordkindDayNumber,
        dbo.ufn_WordkindDayNumber(Date) as FN_WordkindDayNumber

FROM cte_LastDayofPreviousMonth;



回答3:


I created this solution which I think is simple, because you don't need to create a table:

DECLARE @Begin DATETIME = '20160628'
DECLARE @End DATETIME = '20160802 23:59'

;WITH Cte AS
(
    SELECT
        @Begin AS 'Dia'
        ,DATEPART(WEEKDAY,@Begin) AS DiaSemana

    UNION ALL

    SELECT 
        CteADD.Dia
        ,DATEPART(WEEKDAY,CteADD.Dia) AS DiaSemana
    FROM        
        Cte
        CROSS APPLY (SELECT DATEADD(DD,1,Cte.Dia) AS Dia ) CteADD
    WHERE
        CteADD.Dia < @End   
)       

SELECT
    DiaSemana
    ,COUNT(DiaSemana) AS 'QntDias'
FROM
    Cte
GROUP BY
    DiaSemana


来源:https://stackoverflow.com/questions/24834975/count-of-weekdays-in-a-given-month

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!