SQL

[HackerRankSQL] Symmetric Pairs

dontgive 2024. 2. 2. 16:03
728x90

https://www.hackerrank.com/challenges/symmetric-pairs/problem

 

Symmetric Pairs | HackerRank

Write a query to output all symmetric pairs in ascending order by the value of X.

www.hackerrank.com

 

 

HackerRank 문제들을 풀면서 일반적으로는 문제에서 지시하는 사항을 따라가면 자연스럽게 쿼리가 완성되는 경험을 하곤 했던 나에게 조금은 생소하면서도 "아하" 하는 깨우침을 주었던 문제였다. 특히나 "집계"를 조회 결과에 보이도록 하는 부분에만 집중하여 목적으로 사용했던 나에게 "집계"를 과정으로 사용하는 이 문제는 새로운 관점을 던져주었다고 생각되어 정리해보았다.

 

문제 소개

 

문제만 보면 이게 다인가? 싶을 정도로 굉장히 단순하다.

처음에 나도 단순하게 생각하고 문제에 있는 그대로 쿼리를 작성하게 되었다.

 

SELECT f1.X
	, f1.Y
FROM Functions AS f1
	INNER JOIN Functions AS f2 ON (f1.X=f2.Y AND f2.X=f1.Y)
WHERE f1.X <= f1.Y
ORDER BY f1.X

 

두둥.. 그런데 테스트케이스에서 통과되지 않았다...

여기서부터 고민이 시작되게 되었다.

 

f1.X=f2.Y AND f2.X=f1.Y

이 부분에 있는 치명적인 문제를 발견하게 되었다.

 

(x, y) = (1, 2) 인 경우

(1, 2) = (y', x') 인 x', y'을 찾기 위해서는 테이블 내에 (2,1) 레코드가 존재해야 한다.

(x, y) = (1, 1)인 경우

(1, 1) = (y', x') 인 x', y'을 찾는 경우 테이블 내에 다른 (1,1)이 존재하지 않아도 스스로 부합되는 조건이 발생한다.

 

문제는 "한 쌍" 즉 "Pair"를 이루는 데이터들에 대해 말하고 있기 때문에 x=y인 레코드의 경우에는

x!=y인 레코드와 별도로 고려해서 조건을 주어야 할 필요가 있다.

 

즉, x=y인 경우에는 같은 (x,y)가 적어도 두개 이상 존재해야 한다는 추가 조건이 필요하다.

 

레코드의 중복을 체크하는 방법

"같은 (x,y)의 개수를 세야 한다."

"Count 해야 한다."

"COUNT()를 써야 한다."

"COUNT는 집계함수이다."

"집계함수를 쓰기 위해서는 GROUP BY를 써야 한다."

"GROUP BY를 쓰기 위해서는 SELECT 앞부분에 GROUP BY 조건 컬럼을 함께 써주어야 한다."

 

이러한 사고의 흐름을 통해 f1.X와 f1.Y로 기준을 잡고(GROUP BY)

아래와 같이 쿼리를 수정하게 되었다.

 

SELECT f1.X
    , f1.Y
FROM Functions AS f1
    INNER JOIN Functions AS f2 ON f1.X=f2.Y AND f2.X=f1.Y
GROUP BY f1.X, f1.Y
-- HAVING 절 추가 (x=y or x!=y)
ORDER BY f1.X

case1> (1,1) 처럼 x와 y가 동일한 값일 경우

"f1.x=f1.y" AND "동일한 (f1.x, f1.y)의 개수세기"

= "동일한 f1.x의 개수 세기"

= "COUNT(f1.X) 가 2 이상"

case2> (1, 2) 처럼 x와 y가 다른 값인 경우

"f1.x != f1.y" AND "f1.x <= f1.y"

= "f1.x < f1.y"

 

case1 과 case2는 상호 배타적이므로 합집합 조건을 주면(OR)

아래와 같은 쿼리가 완성된다.

SELECT f1.X
    , f1.Y
FROM Functions AS f1
    INNER JOIN Functions AS f2 ON f1.X=f2.Y AND f2.X=f1.Y
GROUP BY f1.X, f1.Y
HAVING COUNT(f1.X)>=2
    OR f1.X < f1.Y
ORDER BY f1.X

 

SELECT 부분에 집계를 활용하지 않아서 GROUP BY가 필요한 문제라고 처음에 전혀 생각을 못하고 있었는데, 그러한 나의 편견을 가볍게 깬 문제였던 것 같다. 특히 조건을 주는 부분들도 경우를 나누어 생각한 뒤에 다시 합쳐야 하는 부분이 SQL에서 새로운 경험이었다.

728x90

'SQL' 카테고리의 다른 글

[JOIN] LEFT JOIN 효과적으로 사용하기  (0) 2024.02.18
DISTINCT 대신 GROUP BY?  (1) 2024.02.10
[HackerRank SQL] The Report 문제풀이  (2) 2024.01.29
[HackerRank SQL] Top Earners  (0) 2024.01.21