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

[TIL172] leetcode - Find Overbooked Employees

by heestory323 2026. 6. 25.

문제 설명

직원의 회의 기록을 이용하여 한 주 동안 회의 시간이 20시간(주 40시간의 50%)을 초과한 주를 찾고, 각 직원이 이런 주를 몇 번 경험했는지 계산하는 문제였다.

문제에서 구해야 하는 것은 단순히 회의 시간이 긴 직원이 아니라,

  • 한 주 동안 회의 시간이 20시간을 초과한 경우를 찾고
  • 직원별로 그런 주가 몇 번 있었는지 계산한 뒤
  • 2주 이상 회의 중심 직원이었던 직원만 출력하는 것이다.

출력 컬럼은 다음과 같다.

  • employee_id
  • employee_name
  • department
  • meeting_heavy_weeks

이 문제는 집계를 한 번 더 집계하는 2단계 집계(Aggregation of Aggregation) 문제였다.


내가 처음 생각한 접근

처음에는 회의 날짜를 직접 주차로 나누기 위해 CASE WHEN을 사용했다.

예를 들어

  • 2023-06-05 ~ 2023-06-11 → 1week
  • 2023-06-12 ~ 2023-06-18 → 2week

처럼 직접 주를 만들어서 해결하려고 했다.

처음에는 이 방식도 맞다고 생각했다.

왜냐하면 문제에서 주차가 명확하게 정해져 있었기 때문이다.

그리고 주별 회의 시간을 구한 뒤,

윈도우 함수인 COUNT() OVER()를 이용해 회의 중심 주의 개수를 세려고 했다.

접근 자체는 크게 틀리지 않았지만 문제를 한 번에 해결하려고 했던 것이 오히려 복잡한 쿼리를 만들었다.


내가 헷갈렸던 부분

1. COUNT()를 너무 빨리 사용하려고 했다.

가장 많이 헷갈렸던 부분이다.

처음에는

COUNT(*) AS cnt

를 만든 뒤

HAVING SUM(cnt) >= 2

처럼 작성하려고 했다.

하지만 생각해보니 아직 직원별 회의 중심 주가 만들어지지도 않았는데 개수를 세려고 한 것이었다.

이 문제는

회의 데이터

↓

주별 회의시간 계산

↓

20시간 초과인 주만 남김

↓

직원별 개수 계산

순서로 해결해야 했다.

주별 집계가 끝난 후에야 COUNT를 사용할 수 있었다.


2. 윈도우 함수를 사용해야 하는 문제라고 생각했다.

처음에는

COUNT() OVER(PARTITION BY employee_id)

를 사용했다.

하지만 문제를 다시 보니 필요한 것은

"직원별 회의 중심 주 개수"

였다.

이미 주별 집계가 끝난 상태라면

GROUP BY employee_id

COUNT(*)

만 하면 되는 문제였다.

굳이 윈도우 함수를 사용할 필요가 없었다.

이 문제를 통해 윈도우 함수를 사용할지, GROUP BY를 한 번 더 사용할지를 먼저 판단하는 습관이 중요하다는 것을 배웠다.


3. CASE WHEN으로 주차를 직접 만드는 것이 맞을까?

처음에는 날짜 범위를 직접 작성했다.

CASE
WHEN meeting_date BETWEEN ...

하지만 정답에서는

WEEKOFYEAR(meeting_date)

를 사용했다.

내 방식도 문제는 해결할 수 있지만,

날짜가 바뀌거나 기간이 늘어나면 CASE를 계속 수정해야 한다.

 

반면

WEEKOFYEAR()

는 자동으로 주차를 계산해준다.

실무에서는 훨씬 유지보수가 쉬운 방법이라는 것을 알게 되었다.


질문하며 이해한 내용

질문

왜 COUNT를 바로 하면 안 될까?

→ 아직 "회의 중심 주"가 만들어지지 않았기 때문이다.

→ COUNT는 회의 기록을 세는 것이 아니라 회의 중심이었던 주를 세야 한다.


질문

왜 GROUP BY를 두 번 해야 할까?

→ 처음 GROUP BY는 주별 회의시간을 계산하기 위해 필요하다.

→ 두 번째 GROUP BY는 직원별 회의 중심 주 개수를 계산하기 위해 필요하다.

집계 결과를 다시 집계하는 문제였기 때문이다.


질문

CASE WHEN 대신 WEEKOFYEAR()를 사용하는 이유는?

→ CASE는 날짜가 고정된 경우에만 편하다.

→ WEEKOFYEAR()는 날짜가 바뀌어도 자동으로 주차를 계산한다.

→ 실무에서는 날짜 함수가 훨씬 유지보수가 쉽다.


최종 해결 방법

1단계. 직원별 주차별 회의 시간을 계산한다.

회의 데이터는 한 건이 한 행이다.

먼저

직원 + 주

단위로 변경해야 한다.

이를 위해

SUM(duration_hours)

를 이용하여 주당 총 회의 시간을 계산한다.


2단계. 회의 시간이 20시간을 초과한 주만 남긴다.

문제에서 회의 중심 직원의 기준은

20시간 초과

이다.

따라서 이 조건을 만족하는 주만 남긴다.


3단계. 직원별 회의 중심 주 개수를 계산한다.

이제 한 행이

직원의 한 주

를 의미하게 된다.

따라서

COUNT(employee_id)

를 수행하면

회의 중심 직원이었던 주의 개수를 계산할 수 있다.


4단계. 2주 이상인 직원만 출력한다.

마지막으로

HAVING COUNT(employee_id) >= 2

조건을 이용하여

회의 중심 직원이었던 주가 2주 이상인 직원만 남긴다.


정답 쿼리

WITH w AS (
    SELECT
        employee_id,
        SUM(duration_hours) AS TotalHours
    FROM meetings
    GROUP BY
        employee_id,
        WEEKOFYEAR(meeting_date),
        YEAR(meeting_date)
)

SELECT
    w.employee_id,
    e.employee_name,
    e.department,
    COUNT(w.employee_id) AS meeting_heavy_weeks
FROM w
JOIN employees e
ON w.employee_id = e.employee_id

WHERE TotalHours > 20

GROUP BY
    w.employee_id,
    e.employee_name,
    e.department

HAVING COUNT(w.employee_id) >= 2

ORDER BY
    meeting_heavy_weeks DESC,
    e.employee_name;

오답 및 시행착오

처음에는

  • CASE WHEN으로 주차를 직접 만들고,
  • COUNT() OVER()를 이용해 주 수를 계산하려고 했다.

하지만 문제를 다시 분석해보니

회의 기록을 바로 세는 것이 아니라

주별 집계 → 직원별 집계

순서가 필요했다.

또한 처음에는 윈도우 함수를 사용하려 했지만,

단순히 직원별 개수를 세는 문제였기 때문에 GROUP BY를 한 번 더 사용하는 것이 훨씬 간단했다.


핵심 SQL 개념 정리

WEEKOFYEAR()

왜 사용하는가?

날짜를 자동으로 몇 번째 주인지 계산하기 위해 사용한다.

실무 활용

  • 주간 매출
  • 주간 방문자 수
  • 주간 KPI
  • 주간 회의 시간

 

CASE WHEN vs WEEKOFYEAR()

내가 사용한 방법

CASE
WHEN meeting_date BETWEEN ...

정답 방법

WEEKOFYEAR(meeting_date)

왜 WEEKOFYEAR()가 더 적절한가?

CASE는 날짜가 고정되어 있을 때는 사용할 수 있지만,

날짜 범위가 바뀌면 계속 수정해야 한다.

반면 WEEKOFYEAR()는 자동으로 주차를 계산하므로 실무에서 더 많이 사용된다.


이번 문제에서 배운 패턴


비슷한 문제가 나오면 어떻게 접근할까?

이 문제는 다음과 같은 유형으로 확장할 수 있다.

  • 월별 우수 직원 찾기
  • 분기별 KPI 달성 횟수 계산
  • 고객별 구매 기준 충족 월 수 계산
  • 매장별 목표 달성 주 수 계산

공통적으로

집계 결과를 다시 집계하는 2단계 집계 문제라는 점을 먼저 떠올려야 한다.

 

오늘 배운 점

집계 결과를 다시 집계해야 하는 문제에서는 윈도우 함수보다 GROUP BY → 조건 필터링 → GROUP BY 흐름이 훨씬 자연스럽고 간단할 수 있다는 것을 배웠다.


다음에 같은 문제를 만나면

먼저 데이터의 단위가 어떻게 바뀌는지 확인한다.

원본 데이터의 단위와 최종 결과의 단위가 다르다면 2단계 집계가 필요한 문제인지 먼저 판단한다.


핵심 한 줄 요약

원본 데이터를 원하는 단위(주별)로 먼저 집계한 뒤, 조건을 만족하는 집계 결과를 다시 사람 기준으로 집계하는 것이 이 문제의 핵심 패턴이다.