If I have a many to many relationship, agents that can have many properties, and vice versa, defined in a in a junction table, how would I query the "top" agents (an agent who has at least two properties in common with two other agents.)
agent_properties
agent_id | property_id |
---|---|
1 | 1 |
1 | 2 |
1 | 3 |
2 | 2 |
2 | 3 |
3 | 1 |
3 | 3 |
3 | 5 |
4 | 3 |
4 | 4 |
4 | 6 |
5 | 1 |
5 | 2 |
5 | 5 |
6 | 4 |
6 | 6 |
Agent 1 (propr1, propr2, propr3),
Agent 2 (propr2, propr3),
Agent 3 (propr1, propr3, propr5)
Agent 4 (propr3, propr4, propr6)
Agent 5 (propr1, propr2, propr5)
Agent 6 (propr4, propr6)
So the query should return Agent 1, Agent 3, Agent 5
Agent 1 (he has at least two properties in common with agent2 and agent3).
Agent 3 (he has at least two properties in common with agent1 and agent5).
Agent 5 (he has at least two properties in common with agent1 and agent3).
an agent who has at least two properties in common with two other agents.
Count the number of agents per property (using window functions). Then take the agents where there are at least two properties with two agents:
select agent_id
from (select ap.*,
count(*) over (partition by property_id) as num_agents
from agent_properties ap
) ap
where num_agents > 2 -- properties that are shared have more than two agents
group by agent_id
having count(*) >= 2; -- at least two properties that are shared
Here is a db<>fiddle.
EDIT:
Oh, I see. I was going down the wrong path looking at properties first and then agents.
You want a self join with aggregation to calculate the number of properties in common between two agents. Then you want limits in that aggregation:
select agent_id
from (select ap1.agent_id, ap2.agent_id as agent_id2, count(*) as properties_in_common
from agent_properties ap1 join
agent_properties ap2
on ap1.property_id = ap2.property_id and ap1.agent_id <> ap2.agent_id
group by ap1.agent_id, ap2.agent_id
) aa
where properties_in_common >= 2
group by agent_id
having count(*) >= 2
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments