我有很多表连接在一起进行查询,结果有几列。我将重点关注两个吸引我的专栏:“客户”和“职位”。
我需要为位置为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
答案 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 = 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
。
答案 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
)
);