sql查询,只查找具有2个源值的客户ID

mzsu5hc0  于 2021-07-26  发布在  Java
关注(0)|答案(3)|浏览(357)

我有两个表,一个存储customer id,另一个存储customer id以及使用该customer信息的不同来源的信息。示例:表a

Customer Id
1
2
3
..

表b

Customer Id Source
1            'AA'
2            'AA'
1            'AB'
2            'AB'
2            'AC'
3            'AA'
3            'AB'
3            'AE'
4            'AA'
4            'AB'

我想写一个sql查询,它返回只有aa和ab作为源的记录(没有其他源)
我已经编写了以下查询,但无法正常工作:

select a.customer_id
  from A a, B b
 where a.customer_id = b.customer_id
   and b.source IN ('AA','AB')
 group by a.customer_id
having count(*) = 2;
g0czyy6m

g0czyy6m1#

一个相当有效的解决方案是 exists 子查询:

select a.*
from a
where
    exists(select 1 from b where b.customer_id = a.customer_id and b.source = 'AA')
    and exists(select 1 from b where b.customer_id = a.customer_id and b.source = 'AB')
    and not exists(select 1 from b where b.customer_id = a.customer_id and b.source not in ('AA', 'AB'))

带索引的 b(customer_id, source) ,这应该运行得很快。
另一种选择是侵害:

select customer_id
from b
group by customer_id
having
    max(case when source = 'AA' then 1 else 0 end) = 1
    and max(case when source = 'AB' then 1 else 0 end) = 1
    and max(case when source not in ('AA', 'AB') then 1 else 0 end) = 0
8wtpewkr

8wtpewkr2#

这假设customer\u id/源组合没有重复项

select a.customer_id
  from A a join B b
    on a.customer_id = b.customer_id
 group by a.customer_id
-- both 'AA' and 'AB', but no other
having sum(case when b.source IN ('AA','AB') then 1 else -1 end) = 2

在联接之前进行聚合可能更有效:

select a.customer_id
from A a join 
  ( select customer_id
    from B b
    group by customer_id
    -- both 'AA' and 'AB', but no other
    having sum(case when source IN ('AA','AB') then 1 else -1 end) = 2
  ) b
on a.customer_id = b.customer_id
6vl6ewon

6vl6ewon3#

可以使用聚合:

select b.customer_id
from b
where b.source in ('AA', 'AB')
group by b.customer_id
having count(distinct b.source) = 2;

也就是说,你的版本应该可以用。然而,你应该学会使用适当的,明确的,标准的,可读的 JOIN 语法。但是,在这种情况下不需要连接。
如果只需要这两个源,则需要调整逻辑:

select b.customer_id
from b
group by b.customer_id
having sum(case when b.source = 'AA' then 1 else 0 end) > 0 and  -- has AA
       sum(case when b.source = 'AB' then 1 else 0 end) > 0 and  -- has AB
       count(distinct b.source) = 2;

相关问题