TSQL - группа фильтров, если она содержит все нули - PullRequest
0 голосов
/ 15 ноября 2018

Я хотел бы отфильтровать группу, которая содержит все нулевые значения для TASK_START и TASK_END, которые будут B и D.

Пример данных таблицы

+----+-------+-------------------------+-------------------------+-------------------------+-------------------------+
| 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                    |
+----+-------+-------------------------+-------------------------+-------------------------+-------------------------+

Ответы [ 3 ]

0 голосов
/ 15 ноября 2018

Попробуйте это:

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);   

enter image description here

Идея состоит в том, чтобы получить максимальную (или минимальную, если хотите) дату для каждой группы, а затем, если есть строки, где это значение равно NULL, чтобы исключить их.

0 голосов
/ 15 ноября 2018

Я бы просто использовал count() с having:

select id
from table t
group by id
having count(task_start) = 0 and
       count(task_end) = 0;
0 голосов
/ 15 ноября 2018

Вы можете использовать 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
                 );

Другой вариант будет использовать 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;
...