select from_id, to_id, count(*) count_between from ( select from_id, to_id from pm union all select to_id, from_id from pm ) combined where from_id < to_id group by from_id, to_id
Full sample
CREATE TABLE pm (from_id int,to_id int); insert pm select 1,2; insert pm select 1,2; insert pm select 1,2; insert pm select 1,2; insert pm select 1,2; insert pm select 2,1; insert pm select 2,1; insert pm select 2,1; insert pm select 3,4; insert pm select 3,4; insert pm select 4,3; select from_id, to_id, count(*) count_between from ( select from_id, to_id from pm union all select to_id, from_id from pm ) combined where from_id < to_id group by from_id, to_id
To include identifiers in names, use the regular user table or some of them. eg.
select u1.name from_, u2.name to_, count(*) count_between from ( select from_id, to_id from pm union all select to_id, from_id from pm ) combined join users u1 on u1.id = combined.from_id join users u2 on u2.id = combined.to_id where from_id < to_id group by u1.name, u2.name
source share