해당 문제는 LeetCode에서 사용한 문제이며 모든 테이블의 자료와 출처는 LeetCode임을 밝힙니다.
해당 글에서는 SELF JOIN를 사용하여 푸는 문제로 저 같은 초보자에게는 매우 난이도가 있는 문제인 것 같습니다.
해당 문제 원본을 확인 하시려면 해당 사이트를 들어가시면 될 것 같습니다.
시작하겠습니다.
Write a solution to find all dates' id with higher temperatures compared to its previous dates (yesterday).
(이전 날짜(어제)에 비해 온도가 높은 모든 날짜의 ID를 찾는 솔루션을 작성합니다.)
이 문제에서는 우선 Weather라는 테이블이 주어졌으며 이전 날짜에 비해 온도가 높은 모든 날짜의 ID를 출력하는 것입니다.
즉, 오늘 날짜 기온과 어제 날짜 기온이 하나의 행에 있으면 풀기 매우 수월 할 것 같습니다.
문제를 풀기 전 DATE 형식으로 된 날짜 더하는 방법에 대해 짚고 넘어가겠습니다. (MySQL 기준)
MySQL 시간 더하기 - DATE_ADD (기준날짜, INTERVAL)
예 : DATE_ADD(SYSDATE(), INTERVAL 1 SECOND) => 1초
DATE_ADD(SYSDATE(), INTERVAL 1 MINIUTE) => 1분 뒤
DATE_ADD(SYSDATE(), INTERVAL 1 HOUR) => 1 시간 뒤
DATE_ADD(SYSDATE(), INTERVAL 1 DAY) => 하루 뒤
DATE_ADD(SYSDATE(), INTERVAL 1 MONTH) => 1달 뒤
DATE_ADD(SYSDATE(), INTERVAL 1 YEAR) => 1년 후
DATE_ADD(SYSDATE(), INTERVAL -1 YEAR) => 1년 전
날짜 형식을 더할 경우는 해당 함수를 써줘야 합니다. 그 이유는 그냥 +1을 하게 되면 1-31 -> 1-32로 되기 때문입니다.
1. 오늘 날짜와 어제 날짜를 기준으로 JOIN하기
Select today.recordDate
, today.temperature
, yesterday.recordDate
, yesterday.temperature
FROM Weather today
INNER JOIN Weather yesterday
ON today.recordDate = DATE_ADD(yesterday.recordDate, INTERVAL 1 DAY)
["recordDate", "temperature", "recordDate", "temperature"]
["2015-01-02", 25, "2015-01-01", 10],
["2015-01-03", 20, "2015-01-02", 25],
["2015-01-04", 30, "2015-01-03", 20]
위의 코드 결과와 같이 오늘날짜, 오늘온도, 어제 날짜, 어제 기온이 한 행에 묶인 것을 볼 수 있습니다.
2. WHERE 절을 통해 오늘 온도와 어제 온도 비교하기
Select today.recordDate
, today.temperature
, yesterday.recordDate
, yesterday.temperature
FROM Weather today
INNER JOIN Weather yesterday
ON today.recordDate = DATE_ADD(yesterday.recordDate, INTERVAL 1 DAY)
WHERE
today.temperature > yesterday.temperature
["recordDate", "temperature", "recordDate", "temperature"]
["2015-01-02", 25, "2015-01-01", 10]
["2015-01-04", 30, "2015-01-03", 20]
결과 어제보다 오늘 온도가 더 높은 날짜인 행만 출력된 것을 확인하실 수 있습니다.
이제 저희는 id 값만 필요 하므로 id를 추출하겠습니다.
3. 모든 조건 만족 id값 추출하기
Select today.id
FROM Weather today
INNER JOIN Weather yesterday
ON today.recordDate = DATE_ADD(yesterday.recordDate, INTERVAL 1 DAY)
WHERE
today.temperature > yesterday.temperature
오늘의 id의 값이 필요하므로 today의 id 값을 가져왔습니다. 이렇게 하면 모든 테스트 케이스가 통과가 될 것입니다.
4. id를 기준으로 JOIN할 경우
Select today.id
FROM Weather today
INNER JOIN Weather yesterday
ON today.id = yesterday.id + 1
WHERE
today.temperature > yesterday.temperature
위의 코드와 같이 처음에 저는 날짜를 기준으로 JOIN하지 않고 id를 기준으로 합친 결과 테스트 케이스에서 틀린 것을 확인 할 수 있었습니다.
틀린 경우는 모든 날짜가 순서대로가 아닌 경우였습니다. 그래서 id를 기준으로 JOIN을 하게되면 해당 코드가 정확한 추출을 하지 못하게 됩니다.
그래서 문제에서 제시한 내용 그대로 날짜를 사용하여 해야합니다.
그리고 무조건 AS(별칭)을 사용해주면 좋습니다. 왜냐하면 나중에 필요한 값을 쉽게 찾아 뽑아낼 수 있기 때문입니다.
위의 내용들을 잘 숙지하신다면 쉽게 푸실 수 있습니다.
이상으로 Leet Code 문제풀이를 마치도록 하겠습니다.
'Data Analyst > SQL' 카테고리의 다른 글
[SQL] Programmers 문제 풀기 (연도별 대장균 크기의 편차 구하기) (0) | 2024.10.25 |
---|---|
[SQL] HackerRank 문제 풀기 (Symmetric Pairs) (0) | 2024.10.15 |
[SQL] INNER JOIN 사용하여 문제 풀기 (Type of Triangle) (0) | 2024.10.11 |
[SQL] CASE 사용하여 문제 풀기 (Type of Triangle) (0) | 2024.10.10 |
[SQL] GROUP BY 사용하여 문제풀기 (Top Earners) (0) | 2024.10.09 |