2016-09-19 4 views
1

私は生産ラインでビジュアライゼーションを作成しようとしています。私たちには数百人の人々が乗っている2つの行があり、それぞれに異なる乗組員シフト戦略があります。私は、レコードをループすることでAccessで必要な結果を生成することができました。 私はそれをSQL Serverにアップスケールして速度を向上させたいと思います。時間当たりの労働時間を計算する方法

誰かが正しい方向に向いていますか?ここで

enter image description here


Accessで動作するVBAコードです。

Public Function MakeLaborData() 

Dim db As dao.Database 
Dim rs As dao.Recordset 
Dim hr As Date 
Dim LaborOn As Date 
Dim LaborOff As Date 
Dim Hours As Double 

Set db = CurrentDb 
Set rs1 = db.OpenRecordset("t_Labor") 'myTable is a MS-Access table created previously 
Set rs2 = db.OpenRecordset("t_Labor_by_Hour") 

Do While Not rs1.EOF 
    LaborOn = rs1.Fields("LABOR_ON").Value 
    If IsNull(rs1.Fields("LABOR_OFF").Value) Then 
     LaborOff = Now() 
    Else 
     LaborOff = rs1.Fields("LABOR_OFF").Value 
    End If 

hr = DateSerial(DatePart("yyyy", LaborOn), DatePart("m", LaborOn), DatePart("d", LaborOn)) + (DatePart("h", LaborOn)/24) 

Do Until hr > LaborOff 
    If LaborOn > hr And LaborOff < hr + 1/24 Then 
    Hours = (LaborOff - LaborOn) * 24 

    ElseIf LaborOn > hr And LaborOff > hr + 1/24 Then 
     Hours = ((hr + 1/24) - LaborOn) * 24 

    ElseIf LaborOn < hr And LaborOff > hr + 1/24 Then 
     Hours = 1 

    ElseIf LaborOn < hr And LaborOff < hr + 1/24 Then 
     Hours = (LaborOff - hr) * 24 

    Else 
     Hours = 0 

    End If 

    With rs2 
    .AddNew 
    !Line_Number = rs1!UNIT 
    !SOI = rs1!JOB 
    !Employee = rs1!Employee 
    !Hour_of_Day = hr 
    !Labor_Hours = Hours 
    .Update 
    End With 

    hr = hr + 1/24 
Loop 



rs1.MoveNext 

Loop 

rs1.Close 
rs2.Close 

End Function 
ボブは1.75時間を働けば、あなたは午前6時30分に開始ボブのための1つの行を持っているでしょうので、私は、スタートを含むテーブルをお勧めしますし、一人あたりの各シフト(作業期間)の時間を停止したい
+1

あなたのデータ構造、試したクエリ、期待される出力を教えてください。スクリーンショットからあなたを援助するにはどうすればよいですか? – artm

+0

OK。サンプルデータセットをここにアップロードするにはどうすればよいですか? –

答えて

2

回帰CTE(Recursive Common Table Expression)を使用して、時間を含むコレクションを生成できます。

declare @dataTable table(UNIT int, JOB varchar(5), EMPLOYEE nvarchar(50), LABOR_ON datetime2(0), LABOR_OFF datetime2(0)) 
INSERT INTO @dataTable 
(UNIT, JOB, EMPLOYEE, LABOR_ON, LABOR_OFF) 
VALUES 
(398,'W9714',N'Ley',DATETIMEFROMPARTS(2015,12,16,11,46,39,0), DATETIMEFROMPARTS(2015,12,16,12,20,07,0)), 
(398,'WSP06',N'Cervantes',DATETIMEFROMPARTS(2016,01,22,11,30,28,0), DATETIMEFROMPARTS(2016,1,22,12,25,56,0)), 
(398,'DN3RT',N'Miller',DATETIMEFROMPARTS(2015,11,2,13,40,46,0), DATETIMEFROMPARTS(2015,11,2,15,01,12,0)), 
(398,'N04TA',N'Kitzmiller',DATETIMEFROMPARTS(2015,10,20,16,22,02,0), DATETIMEFROMPARTS(2015,10,20,19,06,21,0)), 
(398,'N2C54',N'Blackwell',DATETIMEFROMPARTS(2015,12,14,5,38,30,0), DATETIMEFROMPARTS(2015,12,14,10,34,46,0)), 
(398,'NP02M',N'Perryman',DATETIMEFROMPARTS(2015,10,31,5,20,49,0), DATETIMEFROMPARTS(2015,10,31,12,53,43,0)); 

WITH hourCTE as (SELECT 0 as [HourNo] 
UNION ALL 
SELECT [HourNo] + 1 FROM hourCTE WHERE [HourNo] < 23 
), 
DataWithHours as (
SELECT UNIT 
,JOB 
,EMPLOYEE 
,dateadd(hour,HourNo,cast(cast(LABOR_ON as date) as datetime)) as Hour_of_day 
,LABOR_ON 
,LABOR_OFF 
,hourNo 
FROM hourCTE 
join @dataTable on [HourNo] between DATEPART(HOUR,LABOR_ON) and DATEPART(HOUR,LABOR_OFF)) 

SELECT UNIT 
,JOB 
,EMPLOYEE 
,Hour_of_day 
, 
cast(CASE WHEN DATEPART(HOUR,LABOR_ON) = HourNo 
THEN 
DATEDIFF(SECOND,LABOR_ON,DATEADD(HOUR, 1, Hour_of_day))/cast(3600.0 as decimal) 
WHEN DATEPART(HOUR,LABOR_OFF) = HourNo 
THEN 
DATEDIFF(SECOND,Hour_of_day,LABOR_OFF)/cast(3600.0 as decimal) 
ELSE 
1.000 
END as decimal(6,5)) as Labor_Hours 
FROM DataWithHours 
order by unit, EMPLOYEE, HourNo 

次はあなたが句が

見て、このソリューションでは時間の量を計算するためにWHEN

オフ時間の上の労働者と労働者間の時間の数だけCASEを追加したままどこ従業員のデータを結合する必要があります

+0

これは本当に有望なSterydです。誰かが深夜まで働いているときにはうまくいかないようです。 –

+0

ねえ、私はそれを理解しました。正しい方向を指摘してくれてありがとう! –

2

午前8時15分に停止しました。 3営業時間にこれを表示する必要があるのは、データの問題ではなくプレゼンテーションの問題です。午前12時から午後12時まで、1時間ごとに「時間」テーブルを作成することができます。 Hourテーブルをこの新しいテーブルに追加すると、3つの結果が得られます。

+0

Paulに感謝します。私は例をあまりにも単純にしようとしました。あなたは100%正しいです。それは表示/分析の問題です。だから、テーブルの中に時計の時間があれば、その時間にどのように時間を稼ぐことができますか? SQLで時刻表を「動的に」作成する方法はありますか? –