TSQL - 过滤组,如果它包含所有空
Posted
技术标签:
【中文标题】TSQL - 过滤组,如果它包含所有空【英文标题】:TSQL - Filter group if it contains all null 【发布时间】:2018-11-15 10:44:47 【问题描述】:我想过滤掉包含 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 |
+----+-------+-------------------------+-------------------------+-------------------------+-------------------------+
【问题讨论】:
【参考方案1】:试试这个:
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
的行,则排除它们。
【讨论】:
【参考方案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;
【讨论】:
不会也从 A 中删除该字段吗? @Kyrive。 . .是的,它会删除A
,因为TASK_START
& TASK_END
不为空。【参考方案3】:
我会简单地将count()
与having
一起使用:
select id
from table t
group by id
having count(task_start) = 0 and
count(task_end) = 0;
【讨论】:
以上是关于TSQL - 过滤组,如果它包含所有空的主要内容,如果未能解决你的问题,请参考以下文章