2017-01-24 31 views
1

我試圖在幾分鐘內得到兩個日期之間的差異,是否可能從這個計算中排除午餐時間(又名13:30-14:00)我的SQL語句。什麼我目前做如下:SQL Server:DATEDIFF在兩個日期內排除一定的時間

例排

SetupStart     StartTime     SetupTime 
---------------------------------------------------------------- 
2017-01-23 12:56:42.000  2017-01-23 14:41:06.000  105 

我現在的語句:

DATEDIFF(MINUTE, UserData.Orders.SetupStart, UserData.Orders.StartTime) AS[SetupTime] 

編輯:--------------

這是我目前的Select語句

SELECT DISTINCT 
        TOP (100) PERCENT UserData.Resources.Name AS Resource, UserData.Orders.OrderNo, UserData.Orders.StringAttribute4 AS Customer, UserData.Orders.Product, 
        CEILING(UserData.Orders.OpNo10Quantity) AS OpNo10Quantity, UserData.Orders.NumericalAttribute12 AS Speed, UserData.Orders.SetupStart, UserData.Orders.StartTime, 
        UserData.Orders.EndTime, CASE ToggleAttribute1 WHEN 1 THEN 'Yes' ELSE 'No' END AS Packed, UserData.Orders.StringAttribute5 AS OrderInstructions, UserData.Orders.NextResource, 
        UserData.Orders.DatasetId, UserData.Orders_Dataset.name AS ScheduleName, UserData.Orders.ShowOnReport, dbo.tblPreactorExportFullv10.Length AS L, 
        dbo.tblPreactorExportFullv10.Thickness AS T, dbo.tblPreactorExportFullv10.fWidth AS W, 
DATEDIFF(MINUTE, UserData.Orders.SetupStart, UserData.Orders.StartTime) AS [SAM SetupTime] 
FROM   UserData.Orders INNER JOIN 
        UserData.Resources ON UserData.Orders.Resource = UserData.Resources.ResourcesId AND UserData.Orders.Resource = UserData.Resources.ResourcesId INNER JOIN 
        UserData.Orders_Dataset ON UserData.Orders.DatasetId = UserData.Orders_Dataset.DatasetId AND UserData.Orders.DatasetId = UserData.Orders_Dataset.DatasetId INNER JOIN 
        dbo.tblPreactorExportFullv10 ON UserData.Orders.PartNo = dbo.tblPreactorExportFullv10.ProductCode 
WHERE  (UserData.Orders.DatasetId = 15) AND (UserData.Resources.Name = 'Moulder 6') AND (UserData.Orders.ShowOnReport = 1) 
      AND (UserData.Orders.OperationProgress <> 5) 
ORDER BY UserData.Orders.SetupStart 
+0

減去午休時間(30分鐘)。 –

+0

是的,當我們的用戶可以知道兩個日期在午餐時間之間時,他們正在手動執行此操作。但我不確定如何從SQL自動執行此操作 – Bunion

回答

1

我相信戈登的回答會更快,但另一個選項如下:

(編輯:只是爲了好玩,跑這20,000記錄,並以238毫秒返回)

Declare @YourTable table (SetupStart datetime, StartTime datetime) 
Insert Into @YourTable values 
('2017-01-23 12:56:42.000','2017-01-23 14:41:06.000'), 
('2017-01-23 15:00:00.000','2017-01-23 18:30:00.000'), -- No Lunch 
('2017-01-23 23:51:00.000','2017-01-23 23:53:46.000'), -- Anomoly mentioned 
('2017-01-23 13:15:00.000','2017-01-23 13:45:00.000') -- Started After Lunch 

Select A.* 
     ,B.* 
From (... your complex query here ...) A 
Cross Apply (
       Select SetupTime = count(*) 
       From (Select Top (DateDiff(MINUTE,A.SetupStart,A.StartTime)) T=cast(DateAdd(MINUTE,Row_Number() Over (Order By Number)-1,A.SetupStart) as time) 
         From master..spt_values) S 
       Where (cast(A.SetupStart as time)<'13:30' and cast(A.StartTime as time)>'14:00' and T not between '13:30' and '14:00') 
        or (cast(A.SetupStart as time) > '13:30' ) 
        or (cast(A.StartTime as time) < '14:00') 
     ) B 

返回從安裝時間

SetupStart    StartTime     SetupTime 
2017-01-23 12:56:42.000 2017-01-23 14:41:06.000 75 
2017-01-23 15:00:00.000 2017-01-23 18:30:00.000 210 
2017-01-23 23:51:00.000 2017-01-23 23:53:46.000 2 
2017-01-23 13:15:00.000 2017-01-23 13:45:00.000 30 
+0

我會在早晨約翰給你一個回去,回到你身邊!真的很感激回覆 – Bunion

+0

@Bunion請讓我知道。好奇,如果我正確地陷入邏輯 –

+0

只是想知道我將如何將這個邏輯應用到我的查詢現在,從另一個選擇 – Bunion

0

這是SQL Server中的痛苦,但你可以做到這一點:

(CASE WHEN CAST(o.SetupStart as time) > '14:00:00' OR 
      CAST(o.StartTime as time) < '13:30:00'   
     THEN DATEDIFF(MINUTE, o.SetupStart, o.StartTime) 
     WHEN CAST(o.SetupStart as time) >= '13:30:00' AND 
      CAST(o.StartTime as time) <= '14:00:00' 
     THEN 0 
     WHEN CAST(o.SetupStart as time) >= '13:30:00' 
     THEN DATEDIFF(MINUTE, 
        CAST(CAST(o.SetupStart as DATE) as DATETIME) + CAST('14:00:00' as TIME), 
        o.StartTime 
        ) 
     WHEN CAST(o.StartTime as Time) <= '14:00:00' 
     THEN DATEDIFF(MINUTE, 
        o.SetStart, 
        CAST(CAST(o.StartTime as DATE) as DATETIME) + CAST('13:30:00' as TIME) 
        ) 
     ELSE DATEDIFF(MINUTE, o.SetupStart, o.StartTime) - 30 
    END) AS [SetupTime] 

此處理以下情況:

  • 時報兩個前或午飯後都。
  • 時間都在午餐時間。
  • SetupStart正在吃午飯。
  • StartTime正在吃午飯。
  • SetupStart是午餐前和StartTime是午飯後
+0

這看起來不錯,我會測試一下並回復給您! – Bunion

+0

這給了我不少例外(SetupStart = 2017-01-23 23:51:00.000 start Time = 2017-01-23 23:53:46.0​​00)使用這種情況給了我593 – Bunion

+0

@Bunion。 。 。這應該都是由第一個條件來處理,它應該與您現在使用的代碼相匹配。 –

-1

最簡單的方法是什麼@Shakeer侯賽因建議

DATEDIFF(MINUTE, UserData.Orders.SetupStart, UserData.Orders.StartTime) AS[SetupTime] 

BECOMES

​​

此外,你可以做兩個DATEDIFF功能並將它們加在一起:

DATEDIFF(MINUTE, UserData.Orders.SetupStart, UserData.Orders.LunchStartTime) 
+ DATEDIFF(MINUTE, UserData.Orders.LunchEndTime, UserData.Orders.StartTime) AS[SetupTime] 

如果這些數據點不存在,您可以創建一個臨時表。

+2

我認爲你在這裏忽略了真正的問題,這是一個重疊的測試 - 給出的時間並不總是與午餐時間重疊 - OP需要一種方法來測試如果他們做或不做。如何減去30分鐘不是問題。 – Hogan

+0

感謝Franz的回覆,但Hogan現身。 – Bunion

+0

@Bunion我明白時間是動態的,因此第二個選項(兩個日期與存儲值不同),但你需要那些作爲數據點。如果你正在編寫午餐硬編碼,那麼你應該用硬編碼來代替它們之間的分鐘。假設你有數據點,並且你說'午餐'並不總是在這個時間段內,那麼添加一個CASE WHEN來評估這段時間的午餐是開始,結束還是兩者,然後根據該輸出有不同的DATEDIFF。 –

1
declare 
    @ldt_from time = '13:00' 
    ,@ldt_to time = '14:00'; 

-- dummy data prepare 
;with [my_setups] as 
(
    select [SetupStart] = cast('2017-01-23 13:56:42.000' as datetime), [StartTime] = cast('2017-01-23 14:41:06.000' as datetime) 
    union all 
    select [SetupStart] = cast('2017-01-23 12:45:00.000' as datetime), [StartTime] = cast('2017-01-23 12:46:00.000' as datetime) 
) 
-- end dummy data prepare 
select [minutes] = 
     datediff(mi, [SetupStart], [StartTime]) 
    - datediff(day, [SetupStart], [StartTime]) * (datediff(mi, @ldt_from, @ldt_to)) 
    + case when cast([SetupStart] as time) between @ldt_from and @ldt_to or cast([StartTime] as time) between @ldt_from and @ldt_to then 
     datediff 
     (
     mi 
     ,case when cast([SetupStart] as time) > @ldt_from then cast([SetupStart] as time) else @ldt_from end 
     ,case when cast([StartTime] as time) < @ldt_to  then cast([StartTime] as time) else @ldt_to end  
    ) 
     else 0 end   
from 
    [my_setups] 
+0

我剛剛更新了我的previuos糟糕的工作代碼。請試試這個。你可以忽略我的虛擬數據腳本,而只是使用你的表 – Juozas

相關問題