在SQL查询中删除重复项

时间:2019-08-02 20:26:31

标签: sql sql-server duplicates

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

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

但是客户可以有多个职位,如果客户的职位分别是14和15,我需要过滤掉后者的号码

我尝试使用这篇文章中的逻辑: Using NOT IN with NOT EQUAL when querying

但是,当我使用此方法时,出现一个错误,指出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

3 个答案:

答案 0 :(得分:0)

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

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;

答案 1 :(得分: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

答案 2 :(得分:0)

此解决方案确实适用于大多数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
    )
  );