TSQL-筛选器组(如果包含所有null)

时间:2018-11-15 10:44:47

标签: sql sql-server tsql sql-server-2012

我想过滤出包含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 :(得分:2)

您可以使用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;

答案 1 :(得分:2)

尝试一下:

#include <stdio.h>

int main() {
  char two = '2', three = '3', four = '4', five = '5', six = '6',
       seven = '7', eight = '8', nine = '9';
  char num;

  printf("Enter a phone number: ");

  do {
    num = getchar();
    if(num == 'A' || num == 'B' || num == 'C'){
      num = two;
    }
    else if(num == 'D' || num == 'E' || num == 'F'){
      num = three;
    }
    else if(num == 'G' || num == 'H' || num == 'I'){
      num = four;
    }
    else if(num == 'J' || num == 'K' || num == 'L'){
      num = five;
    }
    else if(num == 'M' || num == 'N' || num == 'O'){
      num = six;
    }
    else if(num == 'P' || num == 'R' || num == 'S'){
      num = seven;
    }
    else if(num == 'T' || num == 'U' || num == 'V'){
      num = eight;
    }
    else if(num == 'W' || num == 'X' || num == 'Y'){
      num = nine;
    }
    printf("%c", num);
  }while(getchar() != '\n');

  return 0;
}

enter image description here

想法是获取每个组的最大(或最小)日期,然后,如果存在其中该值为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); 的行来排除它们,则

答案 2 :(得分:0)

我将count()having一起使用:

select id
from table t
group by id
having count(task_start) = 0 and
       count(task_end) = 0;