2016-09-05 11 views
0

私はSQL(私はそれがT-SQLだと思う)が新しく、Excelで使用した関数をSQLに変換しようとしています。時間をExcelの式をt-sqlに変換

L2は、柱1 G2は、これはありませんが、営業時間は8:45と午前5時PMの間で働いていた計算される列2

=(INT(L2)-INT(G2))*("17:00"-"08:45")+MEDIAN(MOD(L2,1),"17:00","08:45")-MEDIAN(MOD(G2,1),"17:00","08:45") 

なりになります。

作業が翌日の午後4時から午前9時までの場合は、結果は01:15:00になります。

4日目の午前1時から午前9時までの数日間(4時)は17時45分になります。

私はこれを初めて使う人には分かりませんので別の機能を持たない方がいいです。私はSELECT * , <code here here> FROM db.nameセクション内に書くことができます。事前

+0

ここの答えは、T-SQLデータベーステーブルの列1と2の種類が完全に異なると思います。ここで私達を手がかりにすることはできますか? –

+0

返される時間は、特定の増分(すなわち、15分のブロック)または分や秒の正確な数である必要がありますか? – iamdave

+0

問題の列は、datetime形式(yyyy-mm-dd hh:mm:ss)です。正確な時間、分、秒が必要です。 – JayDesu

答えて

2

おかげで私はあなたが機能でこれをしたくないと述べた知っているが、彼らは本当に使いにくいものではなく、あなたがこのために必要とロジックが賢明であることをSQL Serverで複雑すぎますインライン(あなたがの場合は本当にになりたいとは限りませんが、の場合はの男です)。

このパラメータの値が適切でない場合、この関数にはエラー処理はありませんが、値をNULLに学習し、処理フローを処理し、対処する必要がある可能性のあるすべての可能性を十分に考えます:

-- This bit creates your function. You can rename the function from fnWorkingDays to anything you want, though try to keep your naming conventions sensible: 
create function fnWorkingDays(@Start datetime 
          ,@End datetime 
          ) 
returns decimal(10,2) 
as 
begin 
-- Declare the start and end times of your working day: 
declare @WorkingStart time = '08:45:00.000' 
declare @WorkingEnd time = '17:00:00.000' 


-- Work out the number of minutes outside the working day in 24 Hour Notation: 
declare @OvernightMinutes int = datediff(minute           -- Work out the difference in minutes, 
             ,cast(@workingend as datetime)     -- between the end of the working day (CASTing a TIME as DATETIME gives you 1900-01-01 17:00:00) 
             ,dateadd(d,1,cast(@WorkingStart as datetime)) -- and the start of the next working day (CAST the TIME value as DATETIME [1900-01-01 08:45:00] and then add a day to it [1900-01-02 08:45:00]) 
             ) 


-- There is no need to retain the minutes that fall outside your Working Day, to if the very start or very end of your given period fall outside your Working Day, discard those minutes: 
declare @TrueStart datetime = (select case when cast(@Start as time) < @WorkingStart 
             then dateadd(d,datediff(d,0,@Start),0) + cast(@WorkingStart as datetime) 
             else @Start 
             end 
           ) 
declare @TrueEnd datetime = (select case when cast(@End as time) > @WorkingEnd 
             then dateadd(d,datediff(d,0,@End),0) + cast(@WorkingEnd as datetime) 
             else @End 
             end 
           ) 


-- You can now calculate the number of minutes in your true working period, and then subtract the total overnight periods in minutes to get your final value. 
     -- So firstly, if your Working Period is not long enough to stretch over two days, there is not need to do any more than calculate the difference between the True Start and End: 
return (select case when datediff(minute,@Start,@End) < @OvernightMinutes 
      then datediff(minute,@TrueStart,@TrueEnd) 

      -- If you do need to calculate over more than one day, calculate the total minutes between your True Start and End, then subtract the number of Overnight Minutes multiplied by the number of nights. 
      -- This works because DATEDIFF calculated the number of boundaries crossed, so when using DAYS, it actually counts the number of midnights between your two dates: 
      else (datediff(minute,@TrueStart,@TrueEnd) - (datediff(d,@TrueStart,@TrueEnd) * @OvernightMinutes))/1440. 

     -- If you want to return your value in a slightly different format, you could use variations of these two, though you will need to change the RETURNS DECIMAL(10,2) at the top to RETURNS NVARCHAR(25) if you use the last one: 

      -- else datediff(minute,@TrueStart,@TrueEnd) - (datediff(d,@TrueStart,@TrueEnd) * @OvernightMinutes) 
      -- else cast((datediff(minute,@TrueStart,@TrueEnd) - (datediff(d,@TrueStart,@TrueEnd) * @OvernightMinutes))/60 as nvarchar(5)) + ' Hours ' + cast((datediff(minute,@TrueStart,@TrueEnd) - (datediff(d,@TrueStart,@TrueEnd) * @OvernightMinutes))%60 as nvarchar(5)) + ' Minutes' 

      end 
      ) 
end 

go 

そして、これはあなたが関数を呼び出す方法です:

select dbo.fnWorkingDays('2016-09-04 12:00:00.000', '2016-09-06 12:10:00.000') as WorkingDays 

あなたが希望する結果をインラインで取得するには、適切な列名を持つ約2つのDATETIME値を置き換えることができます

select dbo.fnWorkingDays(Dates.StartDate, Dates.EndDate) as WorkingDays 

from (select '2016-09-04 12:00:00.000' as StartDate 
      ,'2016-09-06 12:10:00.000' as EndDate 
      ) as Dates 
関連する問題