class="layout-aside-right paging-number">
본문 바로가기
TIL

[TIL174] leetcode - Find Books with Polarized Opinions

by heestory323 2026. 6. 25.

문제 설명

독서 기록 데이터를 이용하여 독자들의 평가가 극명하게 갈리는 책을 찾는 문제였다.

문제에서 호불호가 극명하게 갈린다고 판단하는 기준은 다음과 같다.

  • 평점이 4점 이상인 기록이 최소 1개
  • 평점이 2점 이하인 기록이 최소 1개
  • 독서 기록이 최소 5개 이상
  • 극단적인 평점(2점 이하 또는 4점 이상)이 전체 독서 기록의 60% 이상

또한 책별로

  • 최고 평점
  • 최저 평점
  • Rating Spread
  • Polarization Score

를 계산하여 출력해야 한다.

출력 컬럼은 다음과 같다.

  • book_id
  • title
  • author
  • genre
  • pages
  • rating_spread
  • polarization_score

이 문제는 조건부 집계(Conditional Aggregation)를 이용하여 특정 조건의 개수를 세고, 비율을 계산하는 집계 문제였다.


내가 처음 생각한 접근

처음에는 책별로

  • 최고 평점
  • 최저 평점
  • 평점 분포

를 계산하면 된다고 생각했다.

그래서

MAX(session_rating)
-
MIN(session_rating)

으로 Rating Spread를 계산했고,

극단적인 평점 개수를 구하기 위해

CASE WHEN session_rating > 3
OR session_rating < 3

조건을 사용했다.

또한

session_rating > 3

이면 높은 평점,

session_rating < 3

이면 낮은 평점이라고 생각하여

Polarized Opinion 조건도 같은 방식으로 작성했다.

집계 방향은 맞았지만 문제에서 요구한 조건을 조금 더 일반적으로 해석한 것이 오답의 원인이었다.

 


최종 해결 방법

1단계. 책별로 그룹을 만든다.

먼저 책별로 독서 기록을 묶는다.

이제 한 그룹이

한 권의 책

을 의미하게 된다.


2단계. 최고 평점과 최저 평점을 계산한다.

MAX(session_rating)

MIN(session_rating)

을 이용하여

Rating Spread를 계산한다.


3단계. 조건부 집계를 이용해 극단적인 평점을 센다.

CASE WHEN session_rating >=4

OR

session_rating <=2

를 이용하여

극단적인 평점 개수를 계산한다.


4단계. Polarization Score를 계산한다.

극단적인 평점 수

/

전체 세션 수

를 계산한다.


5단계. 문제 조건을 만족하는 책만 남긴다.

  • 세션 5개 이상
  • 4점 이상 존재
  • 2점 이하 존재
  • Polarization Score 0.6 이상

조건을 모두 만족하는 책만 출력한다.


내가 작성한 쿼리

-- polarized opinion : 책에 대해 평점 4점과 평점 2점이 각각 하나 이상 있는 경우, 그 책은 호불호가 극명하게 갈린다고 판단합니다
-- 5개의 reading sessions 
-- rating spread = highest_rating - lowest_rating
-- polarization score : 이상치 개수/총session개수 | ROUND(,2)
-- polarization score >= 0.6
-- order by polarization score desc, title desc 
select r.book_id, title, author, genre, pages, 
max(session_rating) - min(session_rating) as rating_spread,
ROUND(SUM(case when session_rating >3 OR session_rating <3 THEN 1 else 0 END) / count(session_id) ,2 ) as polarization_score
from reading_sessions r
JOIN books b ON r.book_id = b.book_id 
group by book_id
having count(session_id) >=5
AND SUM(case when session_rating >3 THEN 1 else 0 END) > 0 
AND SUM(case when session_rating<3 THEN 1 ELSE 0 END) >0
AND polarization_score >= 0.6
order by polarization_score desc, title desc

 


함수 비교 정리

>3 / <3 vs >=4 / <=2

내가 사용한 조건

session_rating >3

session_rating <3

문제 조건

session_rating >=4

session_rating <=2

왜 문제 조건 그대로 작성하는 것이 좋은가?

이번 문제에서는 동일한 결과를 만들지만,

문제를 읽는 사람에게 의도가 더 명확하게 전달된다.

실무에서도 요구사항을 그대로 SQL 조건으로 옮기는 습관이 중요하다.


이번 문제에서 배운 패턴

책별 GROUP BY

↓

최고·최저 평점 계산

↓

조건부 집계

↓

비율 계산

↓

HAVING으로 조건 필터링

↓

정렬

 


다음에 같은 문제를 만나면

먼저

무엇을 세야 하는가?

↓

전체 개수인가?

조건을 만족하는 개수인가?

를 구분한 뒤,

조건부 집계를 사용할지 판단한다.


핵심 한 줄 요약

조건부 집계 문제는 GROUP BY → SUM(CASE WHEN) → 비율 계산 → HAVING 패턴으로 해결하며, 문제의 조건(≥, ≤ 등)은 일반화하지 말고 그대로 SQL에 반영하는 것이 가장 안전하다.