میتونید جدول رو با خودش join کنید البته با شروط مناسب. با این کار میتونید در یک سطر، هم زمان ورود و هم خروج رو داشته باشید. دیگه بقیه محاسبات به راحتی قابل انجام هست.
من جدول با اسکریپت زیر رو ایجاد کردم:
CREATE TABLE [dbo].[Tbl](
[id] [int] IDENTITY(1,1) NOT NULL,
[PersonId] [int] NULL,
[Status] [nvarchar](50) NULL,
[InOutDateTime] [datetime] NULL,
CONSTRAINT [PK_Tbl] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
(Status وضعیت ورود یا خروج رو مشخص میکنه(همون G در مثال شما))
به اینصورت میتونید عمل کنید:
select t1.PersonId,
t1.InOutDateTime as StartDateTime,
t2.InOutDateTime as EndDateTime
from tbl t1
join tbl t2
on t1.PersonId = t2.PersonId
and t1.Status <> t2.Status
and t1.InOutDateTime <= t2.InOutDateTime
آپدیت: کد بالا یک اشکال داره که تمام تاریخها رو ترکیب میکنه و تاریخ های متوالی رو نمیتونه تشخیص بده.