SQL:根据critera删除重复项

时间:2017-06-22 09:41:43

标签: sql sql-server duplicates sql-server-2016

我几乎不熟悉SQL,因此我不太了解它提供的所有高级选项。我目前正在使用MS SQL Server 2016(开发人员版)。

我有以下结果:

|  Type  |  Role  |                 GUID                 |
|--------|--------|--------------------------------------|
|   B    |   0    |                 ABC                  |
|   B    |   0    |                 KLM                  |
|   A    |   0    |                 CDE                  |
|   A    |   0    |                 EFG                  |
|   A    |   1    |                 CDE                  |
|   B    |   1    |                 ABC                  |
|   B    |   1    |                 GHI                  |
|   B    |   1    |                 IJK                  |
|   B    |   1    |                 KLM                  |

从以下SELECT:

SELECT DISTINCT
        Type,
        Role,
        GUID

我想在这些约束之后计算GUID:

- >如果有多个行具有相同的GUID,则只计算“Role”设置为“1”的行,否则计算“Role”设置为0的行 - >如果只有一个,则根据自己的角色值将其计为“角色0”或“角色1”。

我的目标是获得以下结果:

|  Type  |  Role  |              COUNT(GUID)             |
|--------|--------|--------------------------------------|
|   A    |   0    |                  1                   | => counted EFG as there was no other row with a "Role" set to 1
|   A    |   1    |                  1                   | => counted CDE with "Role" set to 1, but the row with "Role" set to 0 is ignored
|   B    |   1    |                  4                   |

2 个答案:

答案 0 :(得分:3)

您的查询未实现您提及的逻辑。这是一个使用子查询和窗口函数的方法:

select type, role, count(*)
from (select t.*,
             count(*) over (partition by GUID) as guid_cnt
      from t
     ) t
where (guid_cnt > 1 and role = 1) or
      (guid_cnt = 1 and role = 0)
group by type, role;

子查询获取与GUID匹配的行数。外部where然后根据您的条件使用它进行过滤。

注意:role不是列名的好选择。它是一个关键字(请参阅here),将来可能会被保留(请参阅here)。

答案 1 :(得分:1)

可以使用NOT EXISTS

例如:

declare @T table ([Type] char(1), [Role] int, [GUID] varchar(3));

insert into @T ([Type], [Role], [GUID]) values
('A',0,'CDE'),
('A',0,'EFG'),
('A',1,'CDE'),
('B',0,'ABC'),
('B',0,'KLM'),
('B',1,'ABC'),
('B',1,'GHI'),
('B',1,'IJK'),
('B',1,'KLM');

select [Type], [Role], COUNT(DISTINCT [GUID]) as TotalUniqueGuid
from @T t
where not exists (
  select 1 
  from @T t1
  where t.[Type] = t1.[Type]
    and t.[Role] = 0 and t1.[Role] > 0
    and t.[GUID] = t1.[GUID]
)
group by [Type], [Role];

<强>返回:

Type Role TotalUniqueGuid
A    0    1
A    1    1
B    1    4