繁体   English   中英

在SQL查询中删除重复项

[英]Removing duplicates in a SQL Query

我有很多表联接在一起进行查询,结果有几列。 我将重点关注两个吸引我的专栏:“客户”和“职位”。

我需要为位置2、3、14和15的每个客户引入数据。

客户可以有多个职位,如果客户的职位是14和15,我需要过滤掉后一个数字

我试过使用这篇文章中的逻辑: 查询时使用NOT IN和NOT EQUAL

但是,当我使用此方法时,出现一个错误,指出Position不在该问题的group by子句中。

select Customer, Position
from Customers

where Position in (2, 3, 14, 15)

我得到的结果当然是这样的:

Customer    Position

Rebecca     3
Jane        2
Charley     14
Charley     15
Adam        2
Adam        14
Frank       3
Frank       14
Frank       15
Joe         3
Joe         15

但是我需要他们看起来像这样。 基本上,当客户有14个时,我需要所有条目,而当列表中已经存在14个时,我就不需要位置15的条目。

Customer    Position

Rebecca     3
Jane        2
Charley     14
Adam        2
Adam        14
Frank       2
Frank       14
Joe         3
Joe         15

您可以使用窗口功能。 像这样:

select Customer, Position
from (select c.*,
             sum(case when position = 14 then 1 else 0 end) over (partition by customer) as has_14
      from Customers c
      where Position in (2, 3, 14, 15)
     ) c
where position <> 15 or has_14 = 0;

对于存在Position = 14Position = 15的情况,可以使用NOT EXISTS:

select c.Customer, c.Position
from Customers c
where 
  c.Position in (2, 3, 14)
  or (
    c.Position = 15
    and
    not exists (
      select 1 from Customers
      where Customer = c.Customer and Position = 14
    )
  )

参见演示。
结果:

> Customer | Position
> :------- | -------:
> Rebecca  |        3
> Jane     |        2
> Charley  |       14
> Adam     |        2
> Adam     |       14
> Frank    |        3
> Frank    |       14
> Joe      |        3
> Joe      |       15

我想Frank在预期结果中错误地将2改为3

该解决方案确实适用于大多数SQL方言,即那些不支持窗口函数的方言。 此外,它仅使用不相关的子查询,这意味着该子查询仅对整个查询执行一次,而不对位置= 15的每一行执行一次:

select Customer, Position
from Customers
where 
  Position in (2, 3, 14)
  or (
    Position = 15
    and
    Customer not in (
      select Customer from Customers where Position = 14
    )
  );

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM