2017-09-21 21 views
1

作業シフトの計算には一般的なケースがあります。関数内で使用することもあれば、コード内で直接使用することもあります。それはコードの年齢によって異なります。ケース最適化

私の質問は、これらのケースを実装するより効率的な方法がありますか?

作成する計算された列は、多くのテーブルからの時間が異なるため、オプションではなく、ほとんどは変更できないテーブルです。

これは、例えばコード

機能

Create Function dbo.wShift(@wTime datetime) 
Returns varchar(21) 
AS 
Begin 
    Return case 
      when DATEPART(weekday,@wTime) between 2 and 6 and cast(@wTime as time) between cast('8:30' as time) and cast('16:30' as time) then 'MON_FRI_8:30-16:30' 
      when DATEPART(weekday,@wTime) = 6 and cast(@wTime as time) >= cast('16:30' as time) 
       or DATEPART(weekday,@wTime) = 2 and cast(@wTime as time) <= cast('8:30' as time) then 'FRI-16:30 to MON-8:30' 
      when DATEPART(weekday,@wTime) in (1,7) then 'FRI-16:30 to MON-8:30'   
      else 'MON_FRI_16:30-8:30' end; 
END 
GO 

サンプルデータと期待される結果

Declare @shiftTimes table (MyDate datetime, eShift varchar(23)) 
INSERT @shiftTimes values 
('2017-01-02 08:31:46.843' ,'MON_FRI_8:30-16:30') 
,('2017-01-03 10:35:21.263' ,'MON_FRI_8:30-16:30') 
,('2017-04-14 17:24:14.900' ,'FRI-16:30 to MON-8:30') 
,('2017-01-06 16:30:51.223' ,'FRI-16:30 to MON-8:30') 
,('2017-01-01 00:24:47.450' ,'FRI-16:30 to MON-8:30') 
,('2017-01-08 14:22:08.920' ,'FRI-16:30 to MON-8:30') 
,('2017-01-02 00:24:11.190' ,'FRI-16:30 to MON-8:30') 
,('2017-04-17 07:15:15.650' ,'FRI-16:30 to MON-8:30') 
,('2017-01-02 16:38:30.860' ,'MON_FRI_16:30-8:30') 
,('2017-01-11 06:27:01.017' ,'MON_FRI_16:30-8:30') 

クエリとテストコードにおける事例の直接実装です

;WITH Cte as 
(
    SELECT 
     MyDate 
     ,eShift 
     ,dbo.wShift(Mydate) wShiftFunction 
     ,case 
      when DATEPART(weekday,MyDate) between 2 and 6 and cast(MyDate as time) between cast('8:30' as time) and cast('16:30' as time) then 'MON_FRI_8:30-16:30' 
      when DATEPART(weekday,MyDate) = 6 and cast(MyDate as time) >= cast('16:30' as time) 
      or DATEPART(weekday,MyDate) = 2 and cast(MyDate as time) <= cast('8:30' as time) then 'FRI-16:30 to MON-8:30' 
      when DATEPART(weekday,MyDate) in (1,7) then 'FRI-16:30 to MON-8:30'   
      else 'MON_FRI_16:30-8:30' 
     end wShiftCase 
    FROM @shiftTimes 
) 
SELECT 
    MyDate 
    ,eShift 
    ,wShiftFunction 
    ,wShiftCase 
    ,CASE WHEN eShift = wShiftFunction THEN 'OK' ELSE 'NOK' END Check_wShiftFunction 
    ,CASE WHEN eShift = wShiftCase THEN 'OK' ELSE 'NOK' END Check_wShiftCase 
FROM 
    cte 
+0

「MON_FRI_16:30-8:30」と「FRI-16:30~MON-8:30」の違いは何ですか? –

+0

MON_FRI_16:30-8:30は、平日の勤務時間が翌日の16:30から8:30になります。 FRI-16:30〜MON-8:30は、金曜日16:30から始まり、月曜日に終了する超過時間です。 –

+0

スカラー関数はなぜここにありますか?代わりにインラインテーブル値関数でなければなりません。 @SeanLange。 –

答えて

2

私はあなたの質問の理由は、これを使用してクエリが遅いと思われる。これがスカラー関数の性質です。これをインラインテーブル値関数に変換し、パフォーマンスの変化量を確認します。このようなもの。

Create Function dbo.wShift(@wTime datetime) 
Returns table 
AS 
    Return select eShift = case 
      when DATEPART(weekday,@wTime) between 2 and 6 and cast(@wTime as time) between cast('8:30' as time) and cast('16:30' as time) then 'MON_FRI_8:30-16:30' 
      when DATEPART(weekday,@wTime) = 6 and cast(@wTime as time) >= cast('16:30' as time) 
       or DATEPART(weekday,@wTime) = 2 and cast(@wTime as time) <= cast('8:30' as time) then 'FRI-16:30 to MON-8:30' 
      when DATEPART(weekday,@wTime) in (1,7) then 'FRI-16:30 to MON-8:30'   
      else 'MON_FRI_16:30-8:30' end; 
GO 
+1

私はあなたの答えに感謝し、私は1つのレポートでそのソリューションをテストしました。私はそれらの時間を得ました:テーブル値関数:1146 ms;ダイレクト・ケース・ステートメント:1147ms;スカラー関数2170 ms –