2017-04-26 53 views
0

如何計算SQL Server 2008R2中從表(從第1行到結尾)的兩個日期之間的計數分鐘數(分鐘計算是星期一上午7點到星期五晚上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之前AM.But我要排除那些minutes.So任何一個可以幫助我在這?

+1

SQL-Server或mysql或Oracle DB?標籤說,MySQL或Qoracle DB和你的問題要求爲SQL服務器 – Jens

+0

只需要爲SQL服務器 – Malyadri

+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); 

很可能有更好的方法來做到這一點,但我基本上打破了問題分解成下列步驟操作:

  • 如果開始日期是在「週末期間」然後向前移動它週一上午7時;
  • 如果結束日期處於「週末期」,則將其移回至週五晚上7點;
  • 計算調整日期之間的分鐘數;
  • 刪除我們在日期範圍內剩下的每個完整週的「週末時間」分鐘數(即週五晚上7點到週一上午的分鐘數)。由於我的調整較早,這應該起作用。

我不確定開始/結束位是否工作100%,因爲您的示例日期不是很好的示例(它們都不在週末期間)。

我試圖按照類似的模式到您的腳本(從根本上不工作順便說一句)。

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 [email protected] 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的一小時差異並不能解釋這種差異。

相關問題