如何计算SQL Server 2008R2中表格(从第1行到结尾)的两个日期之间的分钟计数(分钟计算是星期一上午7点到星期五下午7点)?
我试过这样的东西,但它不起作用
DECLARE @StartDate DateTime='2015-06-12 13:03:00'
DECLARE @EndDate DateTime='2015-06-16 10:08:00'
IF DATEPART(WEEKDAY,@StartDate) = 1
SET @StartDate = DATEADD(HOUR,8,DATEADD(DAY,DATEDIFF(DAY,0,@StartDate),1))
IF DATEPART(WEEKDAY,@StartDate) = 7
set @StartDate = DATEADD(HOUR,8,DATEADD(DAY,DATEDIFF(DAY,0,@StartDate),2))
IF DATEPART(WEEKDAY,@EndDate) = 1
SET @EndDate = DATEADD(HOUR,19,DATEADD(DAY,DATEDIFF(DAY,0,@EndDate),-2))
IF DATEPART(WEEKDAY,@EndDate) = 7
SET @EndDate = DATEADD(HOUR,19,DATEADD(DAY,DATEDIFF(DAY,0,@EndDate),-1))
IF DATEPART(WEEKDAY,@StartDate) = 2 AND DATEPART(HH, @StartDate)<8
SET @StartDate = DATEADD(HOUR, 8, DATEDIFF(DAY, 0, @StartDate))
IF DATEPART(WEEKDAY,@EndDate) = 6 AND DATEPART(HH, @EndDate)>8
SET @EndDate = DATEADD(HOUR, 19, DATEDIFF(DAY, 0, @EndDate))
Declare @WorkMin int
Set @WorkMin=DATEDIFF(MI,@StartDate,@EndDate)-(DATEDIFF(WEEK,@StartDate,@EndDate)*2880)
Print @WorkMin ----Out put is 2705
---------Actual Minutes is 1985
以上代码是在星期五晚上7点和星期一早上7点之前计算分钟数。但我想排除那些分钟。所以有人可以帮我这个吗?
答案 0 :(得分:0)
我得到1985分钟。老实说,我第一次按照你的规则编写脚本时得到了这个,我觉得这很奇怪。
--Working week is 7AM Monday to 7PM Friday
--Get the start date
DECLARE @StartDate DATETIME = '20150612 13:03:00';
--If the start date is in the weekend period then move it forward to 7AM Monday
DECLARE @days INT = NULL;
IF DATEPART(WEEKDAY, @StartDate) = 7 --Saturday
SELECT @days = 2;
IF DATEPART(WEEKDAY, @StartDate) = 1 --Sunday
SELECT @days = 1;
IF DATEPART(WEEKDAY, @StartDate) = 6 AND DATEPART(HOUR, @StartDate) > 19 --Friday after 7PM
SELECT @days = 3;
IF DATEPART(WEEKDAY, @StartDate) = 2 AND DATEPART(HOUR, @StartDate) < 7 --Monday before 7AM
SELECT @days = 0;
IF @days IS NOT NULL
SELECT @StartDate = CONVERT(DATETIME, DATEPART(YEAR, DATEADD(DAY, @days, @StartDate)) + DATEPART(MONTH, DATEADD(DAY, @days, @StartDate)) + DATEPART(DAY, DATEADD(DAY, @days, @StartDate)) + ' 07:00');
--Get the end date
DECLARE @EndDate DATETIME = '20150616 10:08:00';
--If the end date is in the weekend period then move it back to 7PM Friday
SELECT @days = NULL;
IF DATEPART(WEEKDAY, @EndDate) = 7 --Saturday
SELECT @days = -1;
IF DATEPART(WEEKDAY, @EndDate) = 1 --Sunday
SELECT @days = -2;
IF DATEPART(WEEKDAY, @EndDate) = 6 AND DATEPART(HOUR, @EndDate) > 19 --Friday after 7PM
SELECT @days = 0;
IF DATEPART(WEEKDAY, @EndDate) = 2 AND DATEPART(HOUR, @EndDate) < 7 --Monday before 7AM
SELECT @days = -3;
IF @days IS NOT NULL
SELECT @EndDate = CONVERT(DATETIME, DATEPART(YEAR, DATEADD(DAY, @days, @EndDate)) + DATEPART(MONTH, DATEADD(DAY, @days, @EndDate)) + DATEPART(DAY, DATEADD(DAY, @days, @EndDate)) + ' 19:00');
--Now calculate the raw minutes
DECLARE @Minutes INT;
SELECT @Minutes = DATEDIFF(MINUTE, @StartDate, @EndDate);
--Work out how many complete weeks we have, then take this off the result
DECLARE @CompleteWeeks INT = 0;
SELECT @CompleteWeeks = DATEDIFF(WEEK, @StartDate, @EndDate);
SELECT @Minutes = @Minutes - @CompleteWeeks * DATEDIFF(MINUTE, '20170421 19:00', '20170424 07:00'); --3600 minutes, we could just hardcode this
--Output
SELECT 'Start Date' AS metric, CONVERT(VARCHAR(50), @StartDate) AS [value]
UNION ALL
SELECT 'End Date', CONVERT(VARCHAR(50), @EndDate)
UNION ALL
SELECT 'Minutes', CONVERT(VARCHAR(50), @Minutes);
可能有更好的方法可以做到这一点,但我基本上把问题分解为这些步骤:
我不确定开始/结束位是否正常工作,因为您的示例日期不是很好的示例(它们都不是在周末期间)。
我尝试按照与您的脚本类似的模式(从根本上说它没有工作)。
答案 1 :(得分:0)
有些东西不匹配。根据我的计算,该值为1265分钟: manual excel calculation
产生的代码(没有总结)如下。它基于日历表的一个非常具体的版本 - 这是一种你应该学习如何融入你的技能组的技巧。它是静态定义的,包含足够的信息来证明这个特定的问题;我将把它留给你以更通用的方式进行调整。
set nocount on;
declare @cal table (dt_start datetime not null, dt_end datetime not null);
insert @cal(dt_start, dt_end) values
('20150611 07:00', '20150611 19:00'),
('20150612 07:00', '20150612 19:00'), -- friday
('20150615 07:00', '20150615 19:00'),
('20150616 07:00', '20150616 19:00'),
('20150617 07:00', '20150617 19:00'),
('20150618 07:00', '20150618 19:00');
select * from @cal order by dt_start;
declare @ps datetime, @pe datetime;
set @ps = '20150612 13:03';
set @pe = '20150616 10:08';
select @ps as ps, @pe as pe;
select --@ps as [start], @pe as [end],
t.*,
case when t.dt_start < @ps then @ps else t.dt_start end as s1,
case when t.dt_end > @pe then @pe else t.dt_end end as e1,
datediff(minute,
case when t.dt_start < @ps then @ps else t.dt_start end,
case when t.dt_end > @pe then @pe else t.dt_end end ) as calc
from @cal as t
where t.dt_start <= @pe and t.dt_end >= @ps
order by t.dt_start
;
你首先说你的工作时间是早上7点到晚上7点,但你后来说是早上8点到晚上7点。我仍然不太清楚你的计算是如何运作的,但使用8am的一小时差异并不能解释这种差异。