I have a table (`Events`) with the following columns:

    ClientID, EventID, EventName, StartDate, Duration

Consider the following data:

    INSERT INTO Events(ClientID, EventID, EventName, StartDate, Duration) 
    VALUES (1, 1, 'Login', '2016-11-27 1:30:00', 86400000),
           (2, 1, 'Login', '2016-11-27 0:30:00', 86400000),
           (3, 1, 'Login', '2016-11-27 0:00:00', 86400000)

As you can see, the `Duration` is in milliseconds and can span multiple days.

In the end, I would like to return the following for 2016-11-28:

    EventID  EventName  Sum(Duration) Count(ClientID)
    --------------------------------------------------
    1        'Login'     7200000          2 

The question being answered here is "How many clients were logged in on 2016-11-28 and for how many milliseconds?". 86400000 ms is 1 day. So, the first row would have 1.5 hours on 2016-11-28 (1:30 after midnight), the second would have .5 hours (0:30 after midnight), the third would have 0 hours (0:00 after midnight). Add those up, you get 2 hours or 7200000 ms and 2 clients since the 3rd did not have a duration on that day.

I have spent days toying with `CASE` statements to try to do this, and I really feel like there has to a better approach.

    DECLARE @StartDate as DateTime, @EndDate as DateTime
    SET @StartDate = '2016-11-28'
    SET @EndDate = '2016-11-29'

    SELECT 
        EventID, EventName, COUNT(ClientID) AS CountClients,
        SUM(CAST(DATEDIFF(ms, CASE 
                                WHEN StartDate < @StartDate 
                                   THEN @StartDate 
                                ELSE StartDate 
                             END, 
                             CASE 
                                WHEN DATEADD(ms, Duration, StartDate) >= @EndDate 
                                   THEN @EndDate 
                                   ELSE DATEADD(ms, Duration, StartDate) 
                             END) AS bigint)) AS SumDuration
    FROM Events
    WHERE
        ((StartDate >= @StartDate AND StartDate < @EndDate)
        OR (DATEADD(ms, Duration, StartDate) >= @StartDate AND DATEADD(ms, Duration, StartDate) < @EndDate))
    GROUP BY EventID, EventName

I am really struggling with how to do this efficiently, considering that I will need to get partial durations for dates that span more than a day. Any help would really be appreciated.