Here is a solution that uses Run Length Encoding to compress overlapping time ranges -

**SCHEMA AND DESIRED OUTPUT**

``` 
DROP TABLE IF EXISTS dbo.EventTimes;
CREATE TABLE dbo.EventTimes
(
  EventTimeKeyId INT IDENTITY(1,1) PRIMARY KEY,
  EventId INT NOT NULL,
  StartTime TIME NOT NULL,
  EndTime TIME NOT NULL
);

-- Event 1
INSERT INTO dbo.EventTimes (EventId, StartTime, EndTime)
VALUES 
  (1, '04:00:00', '14:00:00'), 
  (1, '06:00:00', '11:00:00'), 
  (1, '09:00:00', '12:00:00'), 
  (1, '13:00:00', '14:00:00'), -- Gap between this row and the next row
  (1, '02:30:00', '04:00:00'); -- Notice the half-hour on this one

-- Event 2
INSERT INTO dbo.EventTimes (EventId, StartTime, EndTime)
VALUES 
  (2, '00:00:00', '06:00:00'), -- Gap between this row and the next row
  (2, '09:00:00', '13:00:00'), 
  (2, '11:00:00', '15:00:00');

-- Final Results expected for these 2 examples
SELECT 1 AS EventId, 11.5 AS TotalTime
UNION ALL
SELECT 2 AS EventId, 12 AS TotalTime;
```
| EventId | TotalTime |
| -------:|---------:|
| 1 | 11.5 |
| 2 | 12.0 |

**Solution**

``` 
WITH x
AS
(
    SELECT EventID
         , MAX(EndTime) AS eID
         , StartTime
    FROM EventTimes
    GROUP BY EventID
           , StartTime
)
   , y
AS
(
    SELECT EventID
         , MIN(x.StartTime) AS stID
         , x.eID
    FROM x
    GROUP BY x.EventID
           , x.eID
)
   , z
AS
(
    SELECT ROW_NUMBER() OVER (ORDER BY y.EventID, y.stID DESC) AS id
         , y.EventID
         , y.stID
         , y.eID
         , IIF((
                   LAG(y.stID) OVER (ORDER BY y.EventID, y.stID DESC) < y.eID
                   AND LAG(y.EventID) OVER (ORDER BY y.EventID, y.stID DESC) = y.EventID
               )
               OR
               (
                   LEAD(y.eID) OVER (ORDER BY y.EventID, y.stID DESC) > y.stID
                   AND LEAD(y.EventID) OVER (ORDER BY y.EventID, y.stID DESC) = y.EventID
               )
             , 1
             , 0) AS grp
    FROM y
)
   , j
AS
(
    SELECT z.EventID
         , z.stID
         , z.eID
         , z.id - RANK() OVER (ORDER BY z.EventID, z.grp, z.stID DESC) AS x
    FROM z
)
   , k
AS
(
    SELECT j.EventID
         , MIN(j.stID) AS stID
         , MAX(j.eID) AS eID
    FROM j
    WHERE j.x < 1
    GROUP BY j.EventID
           , j.x
    UNION ALL
    SELECT j.EventID
         , j.stID
         , j.eID
    FROM j
    WHERE j.x !< 1
)
SELECT EventID
     , CAST(SUM(DATEDIFF(mi, k.stID, k.eID)) AS DECIMAL(5, 1)) / 60 AS EventTime
FROM k
GROUP BY EventID;
```
| EventID | EventTime |
| -------:|---------:|
| 1 | 11.500000 |
| 2 | 12.000000 |

[fiddle for reference](https://dbfiddle.uk/q4CjyH6Z)