【问题标题】:SQL Server calculate number of working dates in a monthSQL Server 计算一个月的工作日期数
【发布时间】:2021-12-18 20:57:00
【问题描述】:

我有下面的示例数据

create table #Calendar (Dates  date)
insert into #Calendar values
('2021-11-01'),('2021-11-02'),('2021-11-03'),('2021-11-04'),('2021-11-05'),('2021-11-06'),
('2021-11-07'),('2021-11-08'),('2021-11-09'),('2021-11-10'),('2021-11-11'),('2021-11-12'),
('2021-11-13'),('2021-11-14'),('2021-11-15'),('2021-11-16'),('2021-11-17'),('2021-11-18'),
('2021-11-19'),('2021-11-20'),('2021-11-21'),('2021-11-22'),('2021-11-23'),('2021-11-24'),
('2021-11-25'),('2021-11-26'),('2021-11-27'),('2021-11-28'),('2021-11-29'),('2021-11-30')

我想要的是计算一个月的工作日数。对于 2021 年 11 月给出的示例数据,如果日期在星期六或星期日,则有 22 个工作日,例如,星期五的工作编号将分配给这些日子 周一 1 周二 2 周三 3 周四 4 周五 5 周六 5 周日 5 周一 7 等,直到我到达每月的最后一天,每个月都会重置

我在下面写了脚本

select
      Dates
      ,DENSE_RANK() OVER (ORDER BY CASE WHEN datepart(DW,Dates)-1 IN (0,6) THEN 5 ELSE datepart(DW,Dates)-1 END) AS WorkingDays
      ,DATENAME(dw,dates) as DaysName
from #Calendar
order by Dates

查询的问题是每周重置为从1开始

电流输出

预期输出

谢谢

【问题讨论】:

  • 你描述它的方式你不想计算,但排名所有天并标记周末。为什么不直接删除周六和周日?如果你真的想要工作日,你需要一个带有国家假期的计算日历表

标签: sql sql-server sql-server-2008


【解决方案1】:

您可以使用滚动条件sum,而不是dense_rank

select
      Dates
      ,sum(case when datepart(DW,Dates)-1 IN (0,6) then 0 else 1 end) over (order by Dates) as WorkingDays
      ,datename(dw,Dates) as DaysName
from #Calendar
order by Dates

【讨论】:

    【解决方案2】:
    DROP TABLE  IF EXISTS #Calendar
    CREATE table #Calendar (Dates  date)
    insert into #Calendar values
    ('2021-11-01'),('2021-11-02'),('2021-11-03'),('2021-11-04'),('2021-11-05'),('2021-11-06'),
    ('2021-11-07'),('2021-11-08'),('2021-11-09'),('2021-11-10'),('2021-11-11'),('2021-11-12'),
    ('2021-11-13'),('2021-11-14'),('2021-11-15'),('2021-11-16'),('2021-11-17'),('2021-11-18'),
    ('2021-11-19'),('2021-11-20'),('2021-11-21'),('2021-11-22'),('2021-11-23'),('2021-11-24'),
    ('2021-11-25'),('2021-11-26'),('2021-11-27'),('2021-11-28'),('2021-11-29'),('2021-11-30')
    
    
    SELECT c.Dates,
           (CASE WHEN DATENAME (dw, c.Dates) IN ( 'Saturday' )
                 THEN LAG (s.WorkingDays, 1, 1) OVER (ORDER BY c.Dates)
                 WHEN DATENAME (dw, c.Dates) IN ( 'Sunday' )
                 THEN LAG (s.WorkingDays, 2, 1) OVER (ORDER BY c.Dates)
                 ELSE s.WorkingDays
            END
           ) AS WorkingDays,
           DATENAME (dw, c.Dates) AS DaysName
    FROM   #Calendar AS c
    LEFT JOIN
           (
               SELECT cc.Dates,
                      ROW_NUMBER () OVER (ORDER BY cc.Dates) AS WorkingDays
               FROM   #Calendar AS cc
               WHERE  DATENAME (dw, cc.Dates) NOT IN ( 'Saturday', 'Sunday' )
           ) AS s
        ON s.Dates = c.Dates][1]][1]
    

    输出 [1]:https://i.stack.imgur.com/Ysw9z.png

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多