Примерно так:
SELECT
t1.UserID,
t1.Date DateStart,
min(CASE
WHEN t2.Event='end' AND t2.Date>t1.Date THEN t2.Date
ELSE null END) DateEnd
FROM table t1
CROSS JOIN table t2
WHERE t1.Event='start'
GROUP BY UserID
хотя, возможно лучше это сделать аналитикой.
Дальше сами. С EventID у вас чтото напутано, поэтому я взял для примера простой понятный вариант. Date переделайте в timestamp: либо в запросе, либо лучше это сделать в БД, чтобы исключить подобные проблемы в будущем.
Если EventId идентификтор одного интервала времени, т.е. в таблице хранится до 2 EventId (начало и конец, или только начало, или ничего), то:
SELECT
t1.UserID,
t1.Date DateStart,
CASE
WHEN t2.Date is null THEN t1.Date
ELSE t2.Date END DateEnd
FROM table t1
LEFT JOIN table t2 ON t1.EventID=t2.EventID AND t1.Date<t2.Date
как-то так. С case выглядит не очень, но так лучше чем cross join с distinct. Ну и вместо date берите timestamp.