What's up !
I used GSquared tables for a solution like this:
-- This is just to create the table for testing.
create table #MachineStatus (
ID int identity primary key,
Time_stamp datetime,
Machine_state int);
insert into #MachineStatus (Time_stamp, Machine_state)
select '3.27.2009 23:00', 0 union all
select '3.27.2009 23:45', 1 union all
select '3.27.2009 23:55', 2 union all
select '3.28.2009 00:30', 1 union all
select '3.28.2009 02:00', 2 union all
select '3.28.2009 04:00', 1 union all
select '3.28.2009 06:00', 2 union all
select '3.28.2009 09:00', 1 union all
select '3.28.2009 16:30', 2 union all
select '3.28.2009 16:50', 0 union all
select '3.28.2009 16:30', 2 union all
select '3.28.2009 18:50', 1 union all
select '3.28.2009 19:50', 2;
create table #Shifts (
ID int identity primary key,
SNumber int,
SStart int,
SStop int);
insert into #Shifts (SNumber, SStart, SStop)
select 1, 8, 17 union all
select 2, 17, 24 union all
select 2, 0, 1 union all
select 3, 1, 8;
-- Here is the actual solution.
;With StatusFlow
AS
(
SELECT Time_Stamp,
Machine_State,
ChangeId = ROW_NUMBER() OVER(ORDER BY Time_Stamp), -- In case the identity gets messed up.
Shift = SNumber
FROM #MachineStatusms
LEFT JOIN #Shifts s ON DATEPART(HOUR,ms.Time_Stamp) BETWEEN s.SStart AND s.SStop
),
Changes AS
(
SELECT Status = ss.Machine_State,
NewStatus = se.Machine_State,
StateStart = ss.Time_Stamp,
StateEnd = se.Time_Stamp,
Duration = DATEDIFF(MINUTE,ss.Time_Stamp, se.Time_Stamp),
ss.Shift
FROM StatusFlow ss
INNER JOIN StatusFlow se ON se.ChangeId = ss.ChangeId + 1
)
SELECT Shift,Status, TotalTime = SUM(Duration)
FROM Changes
GROUP BY Shift,Status
ORDER BY Shift ,Status