sql - 如何从持续时间表 SQL Server 中获取不包括定义的工作日的持续时间?
问题描述
我试图在每个月的周末以外的两个日期之间获得一个持续时间(如果持续时间结合两个月,我有一个两个表(一个用于获取持续时间,另一个用于获取工作日)
我的对象是:
- 将持续时间拆分为每个月,例如:
我想星期五是周末。
DayId DayName
1 Sunday
2 Monday
3 Tuesday
4 Wednesday
5 Thursday
7 Saturday
时长表:
StartDate Endate Duration
2021-03-17 2021-03-25 8
2021-03-28 2021-04-02 5
预期成绩:
StartDate Endate Duration
2021-03-17 2021-03-25 8
2021-03-28 2021-03-31 4
2021-04-01 2021-04-02 1
计算的持续时间(考虑除休息start_date
日之外的日期和end_date
日期=> 星期五
Get_CalendarDate
SQL 函数:
USE [Attendance]
GO
/****** Object: UserDefinedFunction [dbo].[Get_Calendar_Date] Script Date: 3/18/2021 12:26:36 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[Get_Calendar_Date]
(
@StartDate DATETIME
, @EndDate DATETIME
)
RETURNS TABLE
AS
RETURN
(
SELECT Tbl_Obj.RNo
, DATEADD(DAY,Tbl_Obj.RNo-1,@StartDate) AS [Date]
, DATEPART(quarter,DATEADD(DAY,Tbl_Obj.RNo-1,@StartDate)) AS [Quarter]
, DATEPART(dayofyear,DATEADD(DAY,Tbl_Obj.RNo-1,@StartDate)) AS [DayofYear]
, DATEPART(WEEK,DATEADD(DAY,Tbl_Obj.RNo-1,@StartDate)) AS [WeekofYear]
, DATEPART(YEAR,DATEADD(DAY,Tbl_Obj.RNo-1,@StartDate)) AS [Year]
, DATEPART(MONTH,DATEADD(DAY,Tbl_Obj.RNo-1,@StartDate)) AS [Month]
, DATEPART(DAY,DATEADD(DAY,Tbl_Obj.RNo-1,@StartDate)) AS [Day]
, DATEPART(weekday,DATEADD(DAY,Tbl_Obj.RNo-1,@StartDate)) AS [Weekday]
, DATENAME(MONTH,DATEADD(DAY,Tbl_Obj.RNo-1,@StartDate)) AS [MonthName]
, DATENAME(weekday,DATEADD(DAY,Tbl_Obj.RNo-1,@StartDate)) AS [WeekdayName]
, (RIGHT( REPLICATE('0',(4)) +
CONVERT([VARCHAR],DATEPART(YEAR,DATEADD(DAY,Tbl_Obj.RNo-1,@StartDate)),0)
,(4)
)+
RIGHT( REPLICATE('0',(2)) +
CONVERT([VARCHAR],DATEPART(MONTH,DATEADD(DAY,Tbl_Obj.RNo-1,@StartDate)),0)
,(2)
)
) AS [Vintage]
FROM ( SELECT ROW_NUMBER() OVER (ORDER BY [object_id]) AS [RNo]
FROM sys.all_objects WITH (NOLOCK)
) Tbl_Obj
WHERE DATEADD(DAY,Tbl_Obj.RNo-1,@StartDate) <= @EndDate
)
如何从持续时间表 SQL Server 中获取不包括定义的周末的持续时间?
解决方案
我建议使用递归 CTE 扩展天数,然后过滤:
with cte as (
select id, startdate, enddate
from duration
union all
select id, dateadd(day, 1, startdate), enddate
from cte
where startdate < enddate
)
select min(startdate), max(startdate),
sum(case when datepart(weekday, startdate) not in (1, 7) then 1 else 0 end) as duration
from cte
group by id, year(startdate), month(startdate);
这假设每一行都有一个id
,以便更简单地组合一行中的所有结果。
请注意,这使用了星期几的内置函数。我认为您的表没有任何用处,因为它仍然依赖于从datepart()
.
这是一个 db<>fiddle。
推荐阅读
- linux - 为什么当我在命令中使用变量时它会停止工作?|| 外壳脚本
- java - 如何安排任务调用随后将调用 JSON API 的方法
- django - 在两个单独的模型字段 drf 中保存一个值
- python - 使用 matplotlib 和 seaborn 绘制异常值
- macos - 用于查找网络摄像头状态的终端/Shell 脚本
- html - 你如何阻止 iframe 说“站点拒绝连接”?
- html - 左对齐父 div 内内联元素上方和下方的文本
- ios - 如何将 b64 保存为 pdf?
- r - 在 R 中从 Twitter 中抓取特定推文的数据
- java - 发生错误。java.io.FileNotFoundException: test_scores.txt n 发生错误。s.txt(找不到指定的文件) .io.FileInputStreanputStr