I have the table of following structure:
UserID StartedOn EndedOn
1 2009-7-12T14:01 2009-7-12T15:01
2 2009-7-12T14:30 2009-7-12T1
This is NOT a solution. Since, at the time of this posting, the most upvoted solution has a really nasty CROSS JOIN for smaller numbers of rows and a really nasty TRIANGULAR JOIN for larger numbers of rows, I'd thought I'd post some code to make a more substantial amount of test data for people to do their testing with. Let the races begin. ;-)
DROP TABLE #Table
GO
WITH
cteStartedOn AS
(
SELECT TOP 100000 --LOOK! Change this number to vary the number of rows you're testing with.
UserID = ABS(CHECKSUM(NEWID()))%1000,
StartedOn = RAND(CHECKSUM(NEWID()))*DATEDIFF(dd,'2012','2013')+CAST('2012' AS DATETIME)
FROM sys.all_columns ac1, sys.all_columns ac2
)
SELECT UserID, StartedOn,
EndedOn = DATEADD(ss,ABS(CHECKSUM(NEWID()))%36000,StartedOn) --10 hours max
INTO #Table
FROM cteStartedOn;