How to SELECT all records where there is not another record with the same key within a given time offset? What is the best way to perform an SQL query to return all records where there is not another record with a matching id and a timestamp within X time?

So, for example, given the database table sample below and a timeframe of 5 hours, I would want the query to return the sample result.

Sample Data:

id | timestamp
01 | 2015-08-03 03:00:00
01 | 2015-08-03 14:00:00
01 | 2015-08-03 15:00:00
01 | 2015-08-03 16:00:00
02 | 2015-08-03 4:00:00
02 | 2015-08-03 5:00:00
03 | 2015-08-03 2:00:00
03 | 2015-08-03 5:00:00
03 | 2015-08-03 10:01:00

Sample Result:
01 | 2015-08-03 03:00:00
01 | 2015-08-03 16:00:00
02 | 2015-08-03 5:00:00
03 | 2015-08-03 5:00:00
03 | 2015-08-03 10:01:00

...since these are the only records for their respective ids where no other records with matching ids occur in the following 5 hours.

My current solution is to essentially query the entire table and then loop through each record querying on a local datatable. It works but is highly inefficient. Is there an SQL way of doing this? I have looked around for awhile, and I am coming up short. But, I might just not be searching correctly. There is probably some simple solution that I am missing, but I am still pretty new to SQL.

Thanks!

Update:
I should have included the current query I am using for reference. Note that "id" in the sample above really refers to "deviceid" in my actual query. It is:

SELECT id                                   AS 'ID', 
       eventsink.elevatortripevent.deviceid AS 'DeviceID', 
       completed                            AS 'Created', 
       digitalposition                      AS 'DigitalPosition', 
       buildingstate                        AS 'State' 
FROM   eventsink.elevatortripevent 
       JOIN md.elevator 
         ON md.elevator.deviceid = eventsink.elevatortripevent.deviceid 
       JOIN ea.elevatoreventevent 
         ON ea.elevatoreventevent.deviceid = 
            eventsink.elevatortripevent.deviceid 
WHERE  completed &gt;= '8/2/2016 8:13:34 PM' 
       AND completed &lt;= '8/3/2016 8:13:34 PM' 
ORDER  BY eventsink.elevatortripevent.deviceid 


Attempt at Implementing Answer by @irimias

SELECT id              AS 'ID', 
       trip1.deviceid  AS 'Device ID', 
       trip1.completed AS 'Created', 
       digitalposition AS 'Digital Position', 
       buildingstate   AS 'State' 
FROM   eventsink.elevatortripevent trip1 
       LEFT JOIN eventsink.elevatortripevent trip2 
              ON trip1.deviceid = trip2.deviceid 
                 AND trip1.completed &lt; trip2.completed 
                 AND trip1.completed &gt; Dateadd(hh, -5, trip2.completed) 
       JOIN md.elevator 
         ON md.elevator.deviceid = trip1.deviceid 
       JOIN ea.elevatoreventevent 
         ON ea.elevatoreventevent.deviceid = trip1.deviceid 
WHERE  trip2.deviceid IS NULL 
       AND trip1.completed &gt;= '8/2/2016 8:13:34 PM' 
       AND trip1.completed &lt;= '8/3/2016 8:13:34 PM' 
ORDER  BY trip1.deviceid 


Attempt at Implementing Answer by @dnoeth

WITH cte 
     AS (SELECT eventsink.elevatortripevent.deviceid, 
                completed, 
                Lead(completed) 
                  OVER ( 
                    partition BY eventsink.elevatortripevent.deviceid 
                    ORDER BY completed) AS nextTS 
         FROM   eventsink.elevatortripevent) 
SELECT id                                   AS 'ID', 
       cte.deviceid AS 'DeviceID', 
       completed                            AS 'Created', 
       digitalposition                      AS 'DigitalPosition', 
       buildingstate                        AS 'State' 
FROM   cte 
       JOIN md.elevator 
         ON md.elevator.deviceid = cte.deviceid 
       JOIN ea.elevatoreventevent 
         ON ea.elevatoreventevent.deviceid = 
            cte.deviceid 
WHERE  ( nextts IS NULL 
          OR completed &lt; Dateadd(hh, -5, nextts) ) 
       AND completed &gt;= '8/2/2016 8:13:34 PM' 
       AND completed &lt;= '8/3/2016 8:13:34 PM' 
ORDER  BY cte.deviceid
maybe you can try something like :

select ds1.*
from SampleData ds1
left join SampleData ds2 on ds1.id = ds2.id 
    and ds1.timestamp &lt; ds2.timestamp
    and ds1.timestamp &gt; dateadd(hh, -5, ds2.timestamp)
where ds2.id is null