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 |