TSQL datediff 仅营业时间
TSQL datediff only business hours
在一个视图中,这两个日期来自 table:
2014-12-17 14:01:03.523 - 2014-12-20 09:59:28.783
我需要知道以小时为单位的日期差异,假设在一天中我可以计算从早上 8 点到下午 5 点的小时数。
当然不能包括星期六和星期日。
我尝试在 select 中使用此代码,但我只得到几天的差异,不包括周六和周日。
(DATEDIFF(HOUR, convert(datetime,t.EXT_DATAINS-2), convert(datetime,b.EXT_DATAINS-2)) + 1)
-(DATEDIFF(wk, convert(datetime,t.EXT_DATAINS-2), convert(datetime,b.EXT_DATAINS-2)) * 2)
-(CASE WHEN DATENAME(dw, convert(datetime,t.EXT_DATAINS-2)) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, convert(datetime,b.EXT_DATAINS-2)) = 'Saturday' THEN 1 ELSE 0 END) differenza
示例:
2014-12-17 : 3hrs
2014-12-18 : 8hrs
2014-12-19 : 8hrs
2014-12-20 : 2hrs
Tot : 21hrs
使用 Recursive CTE
获取所有带日期的小时数。
方法 1:获取 FromDate 和 ToDate 之间小时数的所有日期
DECLARE @FROMDATE DATETIME='2014-12-17 14:01:03.523'
DECLARE @TODATE DATETIME='2014-12-20 09:59:28.783'
;WITH CTE AS
(
SELECT @FROMDATE FROMDATE
UNION ALL
SELECT DATEADD(HH,1,FROMDATE)
FROM CTE
WHERE FROMDATE<@TODATE
)
SELECT ISNULL(CAST(CAST(FROMDATE AS DATE)AS VARCHAR(12)),'Tot')FROMDATE,
CAST(COUNT(FROMDATE)AS VARCHAR(4))+'hrs' [HOURS]
FROM CTE
WHERE DATEPART(HH,FROMDATE) BETWEEN 9 AND 16
AND DATENAME(DW,FROMDATE)<>'SATURDAY' AND DATENAME(DW,FROMDATE)<>'SUNDAY'
GROUP BY CAST(FROMDATE AS DATE)
WITH ROLLUP
方法 2:获取 FromDate 和 ToDate 之间缺失的日期,其中 8 硬编码为 Hrs
此方法将更易于实施 - 性能调整
DECLARE @FROMDATE DATETIME='2014-12-17 14:01:03.523'
DECLARE @TODATE DATETIME='2014-12-20 09:59:28.783'
;WITH CTE AS
(
-- Get missing dates between FromDate and ToDate
SELECT DATEADD(DAY,1,@FROMDATE) FROMDATE,8 HRS
UNION ALL
SELECT DATEADD(DAY,1,FROMDATE),8
FROM CTE
WHERE FROMDATE < DATEADD(DAY,-1,@TODATE)
)
,CTE2 AS
(
-- Gets the Hours for FromDate
SELECT CAST(@FROMDATE AS DATE) DATES, CAST(CAST(DATEDIFF
(
MINUTE,@FROMDATE,CAST(CAST(CAST(@FROMDATE AS DATE) AS VARCHAR(12))+' 17:00:00' AS DATETIME)
)AS NUMERIC(18,2))/60 AS DECIMAL(18,0)) HRS
WHERE DATENAME(DW,@FROMDATE)<>'SATURDAY' AND DATENAME(DW,@FROMDATE)<>'SUNDAY'
UNION ALL
-- Select Hours in between dates
SELECT CAST(FROMDATE AS DATE) NEWDATE,HRS
FROM CTE
WHERE DATENAME(DW,FROMDATE)<>'SATURDAY' AND DATENAME(DW,FROMDATE)<>'SUNDAY'
UNION ALL
-- Select Hours for ToDate
SELECT CAST(@TODATE AS DATE), CAST(CAST(DATEDIFF
(
MINUTE,CAST(CAST(CAST(@TODATE AS DATE) AS VARCHAR(12))+' 08:00:00' AS DATETIME),@TODATE
)AS NUMERIC(18,2))/60 AS DECIMAL(18,0))
WHERE DATENAME(DW,@TODATE)<>'SATURDAY' AND DATENAME(DW,@TODATE)<>'SUNDAY'
)
-- Use ROLLUP to find the sum of Hours and show it in last row
SELECT ISNULL(CAST(DATES AS VARCHAR(20)),'Tot')DATES,
CAST(SUM(HRS)AS VARCHAR(4))+'hrs' HRS
FROM CTE2
GROUP BY DATES
WITH ROLLUP
@marco burrometo
创建一个静态的 table,它将具有所有日历功能,例如假期功能,周六和周日是假期。对你有很大帮助。
在一个视图中,这两个日期来自 table:
2014-12-17 14:01:03.523 - 2014-12-20 09:59:28.783
我需要知道以小时为单位的日期差异,假设在一天中我可以计算从早上 8 点到下午 5 点的小时数。
当然不能包括星期六和星期日。
我尝试在 select 中使用此代码,但我只得到几天的差异,不包括周六和周日。
(DATEDIFF(HOUR, convert(datetime,t.EXT_DATAINS-2), convert(datetime,b.EXT_DATAINS-2)) + 1)
-(DATEDIFF(wk, convert(datetime,t.EXT_DATAINS-2), convert(datetime,b.EXT_DATAINS-2)) * 2)
-(CASE WHEN DATENAME(dw, convert(datetime,t.EXT_DATAINS-2)) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, convert(datetime,b.EXT_DATAINS-2)) = 'Saturday' THEN 1 ELSE 0 END) differenza
示例:
2014-12-17 : 3hrs
2014-12-18 : 8hrs
2014-12-19 : 8hrs
2014-12-20 : 2hrs
Tot : 21hrs
使用 Recursive CTE
获取所有带日期的小时数。
方法 1:获取 FromDate 和 ToDate 之间小时数的所有日期
DECLARE @FROMDATE DATETIME='2014-12-17 14:01:03.523'
DECLARE @TODATE DATETIME='2014-12-20 09:59:28.783'
;WITH CTE AS
(
SELECT @FROMDATE FROMDATE
UNION ALL
SELECT DATEADD(HH,1,FROMDATE)
FROM CTE
WHERE FROMDATE<@TODATE
)
SELECT ISNULL(CAST(CAST(FROMDATE AS DATE)AS VARCHAR(12)),'Tot')FROMDATE,
CAST(COUNT(FROMDATE)AS VARCHAR(4))+'hrs' [HOURS]
FROM CTE
WHERE DATEPART(HH,FROMDATE) BETWEEN 9 AND 16
AND DATENAME(DW,FROMDATE)<>'SATURDAY' AND DATENAME(DW,FROMDATE)<>'SUNDAY'
GROUP BY CAST(FROMDATE AS DATE)
WITH ROLLUP
方法 2:获取 FromDate 和 ToDate 之间缺失的日期,其中 8 硬编码为 Hrs
此方法将更易于实施 - 性能调整
DECLARE @FROMDATE DATETIME='2014-12-17 14:01:03.523'
DECLARE @TODATE DATETIME='2014-12-20 09:59:28.783'
;WITH CTE AS
(
-- Get missing dates between FromDate and ToDate
SELECT DATEADD(DAY,1,@FROMDATE) FROMDATE,8 HRS
UNION ALL
SELECT DATEADD(DAY,1,FROMDATE),8
FROM CTE
WHERE FROMDATE < DATEADD(DAY,-1,@TODATE)
)
,CTE2 AS
(
-- Gets the Hours for FromDate
SELECT CAST(@FROMDATE AS DATE) DATES, CAST(CAST(DATEDIFF
(
MINUTE,@FROMDATE,CAST(CAST(CAST(@FROMDATE AS DATE) AS VARCHAR(12))+' 17:00:00' AS DATETIME)
)AS NUMERIC(18,2))/60 AS DECIMAL(18,0)) HRS
WHERE DATENAME(DW,@FROMDATE)<>'SATURDAY' AND DATENAME(DW,@FROMDATE)<>'SUNDAY'
UNION ALL
-- Select Hours in between dates
SELECT CAST(FROMDATE AS DATE) NEWDATE,HRS
FROM CTE
WHERE DATENAME(DW,FROMDATE)<>'SATURDAY' AND DATENAME(DW,FROMDATE)<>'SUNDAY'
UNION ALL
-- Select Hours for ToDate
SELECT CAST(@TODATE AS DATE), CAST(CAST(DATEDIFF
(
MINUTE,CAST(CAST(CAST(@TODATE AS DATE) AS VARCHAR(12))+' 08:00:00' AS DATETIME),@TODATE
)AS NUMERIC(18,2))/60 AS DECIMAL(18,0))
WHERE DATENAME(DW,@TODATE)<>'SATURDAY' AND DATENAME(DW,@TODATE)<>'SUNDAY'
)
-- Use ROLLUP to find the sum of Hours and show it in last row
SELECT ISNULL(CAST(DATES AS VARCHAR(20)),'Tot')DATES,
CAST(SUM(HRS)AS VARCHAR(4))+'hrs' HRS
FROM CTE2
GROUP BY DATES
WITH ROLLUP
@marco burrometo
创建一个静态的 table,它将具有所有日历功能,例如假期功能,周六和周日是假期。对你有很大帮助。