[英]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 = 14
和Position = 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.