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

[TIL170] leetcode - Find COVID Recovery Patients

by heestory323 2026. 6. 24.

문제 요약

코로나 검사 기록 테이블에서

  • 양성(Positive) 판정을 받은 뒤
  • 음성(Negative) 판정을 받은 환자

를 찾고,

최초 양성일과 최초 음성일 사이의 회복 기간(Day)을 계산하는 문제였다.


내가 처음 접근한 방법

처음에는

ROW_NUMBER()

를 사용해서

환자별 가장 최근 검사 결과를 찾으려고 했다.

 

이유는

현재 상태가 Negative인지 확인해야 한다

고 생각했기 때문이다.

 

하지만 문제는

현재 상태

X

양성 → 음성 변화 과정

을 찾는 것이 핵심이었다.

따라서 최신 기록만 찾는 방식으로는 해결되지 않았다.


최종 정답 SQL

SELECT
    p.patient_id,
    MIN(p.test_date) AS first_positive_date,
    MIN(n.test_date) AS first_negative_date,
    DATEDIFF(
        MIN(n.test_date),
        MIN(p.test_date)
    ) AS recovery_days
FROM covid_tests p
JOIN covid_tests n
    ON p.patient_id = n.patient_id
    AND p.result = 'Positive'
    AND n.result = 'Negative'
    AND p.test_date < n.test_date
GROUP BY p.patient_id
ORDER BY recovery_days;

SQL 실행 순서

1단계

FROM covid_tests p

양성 기록 후보 생성

2단계

JOIN covid_tests n

음성 기록 후보 생성

3단계

ON
p.patient_id = n.patient_id

같은 환자끼리 연결

4단계

p.result = 'Positive'
AND n.result = 'Negative'

양성 → 음성 관계만 유지

5단계

p.test_date < n.test_date

음성이 양성보다 늦게 발생한 경우만 유지

6단계

GROUP BY patient_id

환자별 집계

7단계

MIN(p.test_date)
MIN(n.test_date)

최초 양성일
최초 음성일 계산

8단계

DATEDIFF()

회복 기간 계산

9단계

ORDER BY recovery_days

회복 기간 기준 정렬


핵심 SQL 개념 정리

Self Join

문제 상황

같은 테이블 안에서

Positive

↓

Negative

관계를 찾아야 했다.

사용 이유

한 테이블 내부의 서로 다른 행을 비교해야 하기 때문


동작 방식

covid_tests

↓

Positive 집합(p)

+

Negative 집합(n)

↓

같은 환자끼리 연결

↓

상태 변화 추적

MIN()

문제 상황

최초 양성일과 최초 음성일을 찾아야 했다.

사용 이유

회복 기간은

최초 음성일

-

최초 양성일

이기 때문이다.

사용 예시

MIN(test_date)

INNER JOIN 조건절 필터링

사용 예시

ON p.patient_id = n.patient_id
AND p.result = 'Positive'
AND n.result = 'Negative'
AND p.test_date < n.test_date

장점

JOIN 후 WHERE

보다

필요한 관계만 JOIN

하는 구조라 가독성이 좋다.


함수 비교 정리

ROW_NUMBER() vs MIN()

내가 사용한 함수

ROW_NUMBER()

목적

최신 검사 결과 찾기

정답 함수

MIN()

목적

최초 양성일
최초 음성일

찾기


차이

함수목적

ROW_NUMBER() 순위 부여
MIN() 최솟값 조회

왜 MIN()이 더 적절했는가

문제는

최신 상태

X

최초 양성일과 최초 음성일

을 구해야 했기 때문이다.


TIMESTAMPDIFF() vs DATEDIFF()

내가 떠올린 함수

TIMESTAMPDIFF()

정답 함수

DATEDIFF()

차이

함수특징

DATEDIFF 날짜 차이(일 단위)
TIMESTAMPDIFF 원하는 단위 지정 가능

예시

DATEDIFF(
'2024-01-10',
'2024-01-01'
)

 

 

TIMESTAMPDIFF(
DAY,
'2024-01-01',
'2024-01-10'
)

결과

9

왜 DATEDIFF가 더 적절했는가

이번 문제는

일(day)

차이만 필요했다.

따라서

DATEDIFF()

가 더 짧고 직관적이다.

반면 세션 길이, 체류시간 같은 문제라면

TIMESTAMPDIFF(SECOND)

가 적합하다.


오늘 배운 점

  1. 상태 변화 추적 문제는 Self Join을 먼저 의심한다.
  2. 최신 상태를 찾는 문제와 최초 발생일을 찾는 문제는 완전히 다르다.
  3. 날짜 차이만 계산한다면 DATEDIFF가 가장 간단하다.
  4. JOIN 조건절에서 필요한 관계를 먼저 제한하면 쿼리가 명확해진다.

다음에 같은 문제를 만나면

상태 변화 추적 → Self Join

최초 발생 시점 → MIN()

최신 상태 → ROW_NUMBER()

를 먼저 검토한다.


핵심 한 줄 요약

이 문제는 최신 상태를 찾는 문제가 아니라,
동일 환자의 Positive → Negative 변화 관계를 Self Join으로 연결하고
MIN()과 DATEDIFF()로 회복 기간을 계산하는 문제였다.