SQL 服务器计算一个月的工作日数
SQL Server calculate number of working dates in a month
我有下面的样本数据
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 开始
当前输出
预期输出
谢谢
而不是 dense_rank
,您可以使用滚动条件 sum
:
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
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
我有下面的样本数据
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 开始
当前输出
预期输出
谢谢
而不是 dense_rank
,您可以使用滚动条件 sum
:
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
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