首页 > 解决方案 > T-SQL 数据清理 - 当元组多次出现时,如果某些属性为 NULL,则备用行

问题描述

带有样本数据的表格

UserID | DateID     | Code      | Type
0815     20191211    'oef'       xx     -> keep that row in the result  
0815     20191211    'oef'       NULL   -> should not be in the result set because  
0916     20191212    'bin'       NULL   -> keep that row in the result set if there is just one occurrence for this User at that day. 

在上面的示例中,类型和代码可以为 NULL。如果 Type 为 NULL,则应应用条件数据清理。第二行不应该在结果集中,因为与第一行的唯一区别是类型为 NULL。第三行在该用户当天仅存在一次,并带有该代码,因此应保留。

我无法想象一个优雅而高效的解决方案来完成这项清理任务。因此,如果有人有想法,我会很高兴。

UserID 和 DateID 上有聚集索引(如果有帮助,我可以将其更改为列存储 - MS SQL Server 2016)。我们正在谈论该表中的 100.000.000 行。

标签: sqlsql-servertsql

解决方案


如果我理解正确,您需要两列中的值不是的所有行NULL

那么你想要NULL的值是没有基于另一列的对应行。根据我解释为您想要的内容:

select t.*
from t
where (t.code is not null and t.type is not null) or
      (t.code is null and
       not exists (select 1
                   from t t2
                   where t2.user = t.user and t2.dateid = t.dateid and
                         t2.code is not null and
                         (t2.type = t.type or t2.type is null and t.type is null)
                  )
      ) or
      (t.type is null and
       not exists (select 1
                   from t t2
                   where t2.user = t.user and t2.dateid = t.dateid and
                         t2.type is not null and
                         (t2.code = t.code or t2.code is null and t.code is null)
                  )
      ) ;

推荐阅读