• Figures, that you'd need to span dates. I have some code that works for data that's date unique, but perhaps you can expand the time table involved once you see what I was up to. Take a look at the following:

    CREATE TABLE #TIMES (

    TOD time PRIMARY KEY CLUSTERED

    )

    ;WITH HRS AS (

    SELECT TOP (24) RIGHT('0' + CAST(ROW_NUMBER() OVER(ORDER BY number) - 1 AS varchar(2)), 2) AS HR

    FROM master.dbo.spt_values

    ),

    MINS AS (

    SELECT TOP (60) RIGHT('0' + CAST(ROW_NUMBER() OVER(ORDER BY number) - 1 AS varchar(2)), 2) AS MINS

    FROM master.dbo.spt_values

    )

    INSERT INTO #TIMES

    SELECT H.HR + ':' + M.MINS

    FROM HRS AS H

    CROSS APPLY MINS AS M

    CREATE TABLE #LOGGING_DATA (

    STAFF_MBR varchar(15),

    SERVICE_DATE date,

    PATIENT varchar(15),

    START_TIME time,

    END_TIME time,

    PATIENT_MINUTES int

    )

    INSERT INTO #LOGGING_DATA

    SELECT 'SUZY STAFF', '06/16/11', 'JOHNNY', '10:00', '10:30', 30 UNION ALL--for staff_mins would count this as 30

    SELECT 'SUZY STAFF', '06/16/11', 'DAVID', '10:30', '11:00', 30 UNION ALL--for staff_mins would count this as 30

    SELECT 'SUZY STAFF', '06/16/11', 'JACKSON', '11:00', '12:00', 60 UNION ALL--overlap

    SELECT 'SUZY STAFF', '06/16/11', 'MADDY', '11:00', '12:00', 60 UNION ALL--overlap

    SELECT 'SUZY STAFF', '06/16/11', 'KEVIN', '11:15', '12:00', 45 UNION ALL--overlap

    SELECT 'SUZY STAFF', '06/16/11', 'SARAH', '11:00', '12:00', 60 UNION ALL--overlap

    SELECT 'SUZY STAFF', '06/16/11', 'JUDY', '13:00', '13:30', 30 UNION ALL--for staff_mins would count this as 30

    SELECT 'SUZY STAFF', '06/16/11', 'JOSEPH', '13:15', '13:45', 15--overlap AND non-overlap counts as 15

    ;WITH MAX_DATA AS (

    SELECT STAFF_MBR, SERVICE_DATE, START_TIME, MAX(END_TIME) AS MAX_END, MAX(PATIENT_MINUTES) AS MAX_MINS

    FROM #LOGGING_DATA

    GROUP BY STAFF_MBR, SERVICE_DATE, START_TIME

    )

    SELECT DISTINCT MD.STAFF_MBR, MD.SERVICE_DATE, T.TOD

    INTO #INTERVALS

    FROM MAX_DATA AS MD

    LEFT OUTER JOIN #TIMES AS T

    ON MD.START_TIME <= T.TOD

    AND MD.MAX_END >= T.TOD

    SELECT I1.STAFF_MBR, I1.SERVICE_DATE, COUNT(I1.TOD) / 2 AS PATIENT_MINS

    FROM #INTERVALS AS I1

    INNER JOIN #INTERVALS AS I2

    ON I1.STAFF_MBR = I2.STAFF_MBR

    AND I1.SERVICE_DATE = I2.SERVICE_DATE

    AND I1.TOD <> I2.TOD

    AND ABS(DATEDIFF(ms, I1.TOD, I2.TOD)) = 60000

    GROUP BY I1.STAFF_MBR, I1.SERVICE_DATE

    ORDER BY I1.STAFF_MBR, I1.SERVICE_DATE

    DROP TABLE #LOGGING_DATA

    DROP TABLE #TIMES

    DROP TABLE #INTERVALS

    It uses the Tally table concept to create a table of time values for a 24-hour day, then identifies all the 1 minute intervals that are covered one way or another by a given staff member. Finally, it counts the intervals, needing to divide by 2 as each pair of times that are 1 minute apart is just 1 interval. I added an additional line to the sample data so that I could test it for an overlapping, but not completely overlapping, interval.

    Steve (aka sgmunson) 🙂 🙂 🙂
    Rent Servers for Income (picks and shovels strategy)