본문 바로가기

[TestDome] Social Network

Social Network

JOIN ON에 OR절은 처음 봐서 당황했다. 처음에 JOIN ON A OR B를 A를 기준으로 JOIN한 경우와 B를 기준으로 JOIN한 경우의 합집합으로 생각했다. 그런데 내가 생각한 답이 보기 중에 없는 것이다. 알고 보니 A 조건을 만족하거나 B조건을 만족하는 행만 가져오되, A와 B 조건 모두 만족하는 행이 없어도 LEFT JOIN이라 null값도 결과에 포함시키는 것이었다. 

 

주어진 SQL 쿼리문을 OR 절을 기준으로 나눠서 생각해보자.

SELECT * FROM users
LEFT JOIN friends
ON users.id = friends.user1
WHERE users.sex = 'f';

 

id name sex user1 user2
3 Mary f null null
4 Brenda f null null

 

위 쿼리에서는 Mary의 id도 Brenda의 id도 user1과 일치하는 행이 없다.

 

SELECT * FROM users
LEFT JOIN friends
ON users.id = friends.user2
WHERE users.sex = 'f';

 

id name sex user1 user2
3 Mary f 1 3
3 Mary f 2 3
4 Brenda f null null

 

위 쿼리에서는 Mary의 id는 user2와 일치하는 행이 있지만, Brenda의 id는 여전히 user2와 일치하는 행이 없다.

 

나는 여기서 users.id = friends.user1 OR users.id = friends.user2를 합집합으로 생각해서 아래와 같은 테이블이 만들어질거라 생각했는데, 

 

id name sex user1 user2
3 Mary f null null
4 Brenda f null null
3 Mary f 1 3
3 Mary f 2 3
4 Brenda f null null

 

users.id = friends.user1 조건을 만족하거나 users.id = friends.user2 조건을 만족하는 행을 반환하는 것이었다.

Mary는 후자만 만족하므로 users.id = friends.user2 조건을 만족하는 행만 반환되는 것이고,

Brenda는 전자도 후자도 만족하지 않지만 LEFT JOIN이므로 null값도 반환한다.

따라서, OR를 포함한 쿼리문의 결과는 다음과 같다.

 

SELECT * FROM users
LEFT JOIN friends
ON users.id = friends.user1 OR users.id = friends.user2
WHERE users.sex = 'f';

 

id name sex user1 user2
3 Mary f 1 3
3 Mary f 2 3
4 Brenda f null null

 

이후 users.id, users.name을 기준으로 GROUP BY하고 users.name, COUNT(*) as count를 SELECT하면 아래와 같다.

 

SELECT users.name, COUNT(*) as count FROM users
LEFT JOIN friends
ON users.id = friends.user1 OR users.id = friends.user2
WHERE users.sex = 'f'
GROUP BY users.id, users.name;

 

name count
Mary 2
Brenda 1