Reputation: 77
I would like to filter out the group which contains all null values for TASK_START & TASK_END which will be B and D.
Sample Table Data
+----+-------+-------------------------+-------------------------+-------------------------+-------------------------+
| ID | STATE | ENTER_STATE | LEAVE_STATE | TASK_START | TASK_END |
+----+-------+-------------------------+-------------------------+-------------------------+-------------------------+
| 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 |
+----+-------+-------------------------+-------------------------+-------------------------+-------------------------+
Upvotes: 1
Views: 345
Reputation: 1269713
I would simply use count()
with having
:
select id
from table t
group by id
having count(task_start) = 0 and
count(task_end) = 0;
Upvotes: 0
Reputation: 43636
Try this:
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);
The idea is to get the maximum(or minimum if you like) date for each group and then, if there are rows where this value is NULL
to exclude them.
Upvotes: 2
Reputation: 50163
You can use not exists
:
select t.*
from table t
where not exists (select 1
from table t1
where t1.id = t.id and t1.task_start is not null and t1.task_end is not null
);
Other option would to use GROUP BY
:
select id
from table t
group by id
having sum(case when task_start is not null then 1 else 0 end) = 0 and
sum(case when task_end is not null then 1 else 0 end) = 0;
Upvotes: 2