SQL の世界に足を踏み入れたとき、私はこの質問に対する答えを求めて昼夜を問わず検索しました。私のニーズにこれに似たものを見つけることができなかったので、他の人が私のように助けを必要とする場合に備えて、自分の質問をして答えることにしました.
これが私が持っているデータの例です。簡単にするために、すべて Job テーブルからのものです。各 JobID には、基本的にランダムな独自の開始時刻と終了時刻があり、重複したり、ギャップがあったり、他のジョブと同時に開始および終了したりする可能性があります。
--Available--
JobID WorkerID JobStart JobEnd
1 25 '2012-11-17 16:00' '2012-11-17 17:00'
2 25 '2012-11-18 16:00' '2012-11-18 16:50'
3 25 '2012-11-19 18:00' '2012-11-19 18:30'
4 25 '2012-11-19 17:30' '2012-11-19 18:10'
5 26 '2012-11-18 16:00' '2012-11-18 17:10'
6 26 '2012-11-19 16:00' '2012-11-19 16:50'
クエリの結果を表示したいのは次のとおりです。
WorkerID TotalTime(in Mins)
25 170
26 120
編集:オーバーラップを無視する必要があることを忘れていました。基本的に、これはこれらの労働者とその仕事を、請負業者ではなく時間給の従業員のように扱うことになっています。たとえば、私が 2 つのジョブ ID を担当し、午後 12 時から午後 12 時 30 分まで両方を開始して終了した場合、従業員としては 30 分間しか支払われませんが、請負業者は 60 分間支払われる可能性があります。仕事ごとに報酬を得る。このクエリのポイントは、従業員に関連付けられているデータベース内のジョブを分析し、その従業員が従業員として扱われているかどうか、特定の時間内に合計で何時間働いたかを調べる必要があることです。
EDIT2: 自分の質問に 7 時間答えさせてくれません。後でそこに移動します。
わかりました、今質問に答えます。基本的に、一時テーブルを使用して、検索しているジョブの最小日時と最大日時の間の各分を作成します。
IF OBJECT_ID('tempdb..#time') IS NOT NULL
BEGIN
drop table #time
END
DECLARE @FromDate AS DATETIME,
@ToDate AS DATETIME,
@Current AS DATETIME
SET @FromDate = '2012-11-17 16:00'
SET @ToDate = '2012-11-19 18:30'
create table #time (cte_start_date datetime)
set @current = @FromDate
while (@current < @ToDate)
begin
insert into #time (cte_start_date)
values (@current)
set @current = DATEADD(n, 1, @current)
end
これで、一時テーブルにすべての分があります。ここで、すべての Job テーブル情報をそれに結合し、必要なものを一度に選択する必要があります。
SELECT J.WorkerID
,COUNT(DISTINCT t.cte_start_date) AS TotalTime
FROM #time AS t
INNER JOIN Job AS J ON t.cte_start_date >= J.JobStart AND t.cte_start_date < J.JobEnd --Thanks ErikE
GROUP BY J.WorkerID --Thanks Martin Parkin
drop table #time
これは非常に単純化された答えであり、誰かが始めるのに適しています。