Попробуйте это:
DECLARE @DataSource TABLE
(
[ID] CHAR(1)
,[STATE] CHAR(2)
,[ENTER_STATE] DATETIME2(0)
,[LEAVE_STATE] DATETIME2(0)
,[TASK_START] DATETIME2(0)
,[TASK_END] DATETIME2(0)
);
INSERT INTO @DataSource
VALUES ('A', 'UP', '2018-11-11 08:00:00.000', '2018-11-11 08:30:00.000', '2018-11-11 08:00:00.000', '2018-11-11 08:10:00.000')
,('A', 'UP', '2018-11-11 09:00:00.000', '2018-11-11 09:30:00.000', NULL, NULL)
,('A', 'UP', '2018-11-11 10:00:00.000', '2018-11-11 10:30:00.000', '2018-11-11 08:20:00.000', '2018-11-11 08:30:00.000')
,('B', 'UP', '2018-11-11 08:00:00.000', '2018-11-11 09:00:00.000', NULL, NULL)
,('B', 'UP', '2018-11-11 09:00:00.000', '2018-11-11 10:00:00.000', NULL, NULL)
,('B', 'UP', '2018-11-11 10:20:00.000', '2018-11-11 11:00:00.000', NULL, NULL)
,('B', 'UP', '2018-11-11 11:00:00.000', '2018-11-11 12:00:00.000', NULL, NULL)
,('C', 'UP', '2018-11-11 08:00:00.000', '2018-11-11 08:20:00.000', '2018-11-11 08:15:00.000', '2018-11-11 08:30:00.000')
,('C', 'UP', '2018-11-11 08:20:00.000', '2018-11-11 08:30:00.000', '2018-11-11 08:20:00.000', '2018-11-11 08:35:00.000')
,('D', 'UP', '2018-11-11 08:00:00.000', '2018-11-11 08:10:00.000', NULL, NULL)
,('D', 'UP', '2018-11-11 08:10:00.000', '2018-11-11 09:10:00.000', NULL, NULL);
WITH DataSource AS
(
SELECT *
,MAX([TASK_START]) OVER (PARTITION BY [ID]) AS [DateStart]
,MAX([TASK_END]) OVER (PARTITION BY [ID]) AS [DateEnd]
FROM @DataSource
)
SELECT *
FROM DataSource
WHERE NOT ([DateStart] IS NULL AND [DateEnd] IS NULL);
Идея состоит в том, чтобы получить максимальную (или минимальную, если хотите) дату для каждой группы, а затем, если есть строки, где это значение равно NULL
, чтобы исключить их.