HEre's a partial solution. It depends on two assumptions:
1. no overlapping time periods
2. no period crosses midnight
Note: This does not return original rows as it stands, just identifies days where the conditions are met
declare @e table (E_CODE VARCHAR(10), [DATE] VARCHAR(10), S_TIME VARCHAR(5), DURATION INT );
INSERT INTO @e VALUES ( 'JOHN', '2014/12/20', '08:00', 1);
INSERT INTO @e VALUES ( 'JOHN', '2014/12/20', '08:01', 1);
INSERT INTO @e VALUES ( 'JOHN', '2014/12/20', '08:02', 58);
INSERT INTO @e VALUES ( 'JOHN', '2014/12/20', '09:00', 30);
INSERT INTO @e VALUES ( 'JOHN', '2014/12/20', '10:00', 45);
INSERT INTO @e VALUES ( 'JACK', '2014/12/20', '08:00', 120);
INSERT INTO @e VALUES ( 'JACK', '2014/12/20', '10:10', 60);
INSERT INTO @e VALUES ( 'JACK', '2014/12/20', '11:30', 60);
SELECT DISTINCT e3.e_code
, e3.date
FROM(
SELECT e2.E_CODE
, e2.DATE
, e2.S_TIME
, CASE
WHEN e2.s_time = DATEADD(minute, e2.lag_dur, e2.lag_time)
OR e2.lag_time IS NULL THEN SUM(e2.duration)
OVER(PARTITION BY e2.e_code, e2.date
ORDER BY e2.s_time
ROWS UNBOUNDED PRECEDING)
ELSE 0
END AS sum_dur
FROM(
SELECT e1.e_code
, e1.date
, e1.s_time
, e1.DURATION
, lag(e1.s_time, 1, NULL) OVER(PARTITION BY e1.e_code, e1.date
ORDER BY s_time) AS lag_time
, lag(e1.duration, 1, 0) OVER(PARTITION BY e1.e_code, e1.date
ORDER BY s_time) AS lag_dur
FROM @e e1
) e2
) e3
WHERE e3.sum_dur >= 90;