Given the following tables:
------------ ------------
| BA | | CA |
------+----- ------+-----
| BId|| AId| | CId|| AId|
I think the simplest solution uses window functions:
select ca.cid, ba.bid
from (select ca.*, count(*) over (partition by cid) as cnt
from ca
) ca join
(select ba.*, count(*) over (partition by bid) as cnt
from ba
) ba
on ca.aid = ba.aid and ca.cnt = ba.cnt
group by ca.cid, ba.bid, ca.cnt
having ca.cnt = count(*) -- all match
Here is a db<>fiddle.
The result set is all matching cid
/bid
pairs.
The logic here is pretty simple. For each cid
and bid
, the subqueries calculate the count of aid
s. This number has to match.
Then the join
is on aid
-- this is an inner join, so only matching pairs are produced. The final group by
is used to generate the count of matches to see if this tallies up with all the aid
s.
This particular version assumes that the rows are unique in each table, although the query can easily be adjusted if this is not the case.