I didn't understand your example -- don't see what all the columns are for, or even which one's got the tag status in it! Nonetheless, your question seems fairly straightforward.Given a table structure like this:CREATE TABLE EntranceLog ( tag_id int NOT NULL, event_time datetime NOT NULL, direction varchar(3) NOT NULL CHECK ( direction IN ('in', 'out') ), PRIMARY KEY (tag_id, event_time))You need to get, for each event, the next event (if any) for the same tag id. You can do this either with a subquery:SELECT E1.tag_id, E1.event_time, E1.direction, E1.next_event_time, E2.direction AS next_directionFROM ( SELECT E1.tag_id, E1.event_time, E1.direction, ( SELECT MIN(E2.event_time) FROM EntranceLog AS E2 WHERE E1.tag_id = E2.tag_id AND E1.event_time < E2.event_time ) AS next_event_time FROM EntranceLog AS E1 ) AS E1LEFT JOIN EntranceLog AS E2 ON E1.tag_id = E2.tag_id AND E1.next_event_time = E2.event_timeORDER BY E1.tag_id, E1.event_time
or a join:SELECT E1.tag_id, E1.event_time, E1.direction, E1.next_event_time, E2.direction AS next_directionFROM ( SELECT E1.tag_id, E1.event_time, E1.direction, MIN(E2.event_time) AS next_event_time FROM EntranceLog AS E1 LEFT JOIN EntranceLog AS E2 ON E1.tag_id = E2.tag_id AND E1.event_time < E2.event_time GROUP BY E1.tag_id, E1.event_time, E1.direction ) AS E1LEFT JOIN EntranceLog AS E2 ON E1.tag_id = E2.tag_id AND E1.next_event_time = E2.event_timeORDER BY E1.tag_id, E1.event_time
depending on how many events per tag_id you have, one or the other may be better: certainly they tend to produce different execution plans.If (tag_id, event_time) is not a candidate key for your event table, you'll need to decide for yourself what two events at the same time for the same tag id mean.You'll have to decide what to do with 'in' events that have never been followed by 'out' events (maybe launch a search party!)You may or may not have to worry about what two or more consecutive 'in' events or 'out' events on given tag id means.