난이도: EASY
문제 링크: Rising Temperature - LeetCode
문제
Table: Weather
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| recordDate | date |
| temperature | int |
+---------------+---------+
id is the column with unique values for this table.
There are no different rows with the same recordDate.
This table contains information about the temperature on a certain day.
Write a solution to find all dates' id with higher temperatures compared to its previous dates (yesterday).
Return the result table in any order.
The result format is in the following example.
Example 1:
Input:
Weather table:
+----+------------+-------------+
| id | recordDate | temperature |
+----+------------+-------------+
| 1 | 2015-01-01 | 10 |
| 2 | 2015-01-02 | 25 |
| 3 | 2015-01-03 | 20 |
| 4 | 2015-01-04 | 30 |
+----+------------+-------------+
Output:
+----+
| id |
+----+
| 2 |
| 4 |
+----+
Explanation:
In 2015-01-02, the temperature was higher than the previous day (10 -> 25).
In 2015-01-04, the temperature was higher than the previous day (20 -> 30).
시도
SELECT A.id
FROM Weather A
JOIN Weather B
ON A.recordDate = B.recordDate - INTERVAL '1' DAY
WHERE A.temperature > B.temperature
어제랑 비교한다는 생각에 빠져서 - INTERVAL '1' DAY로 작성했는데 A가 오늘 B가 어제 인 것을 찾으려면
+ INTERVAL '1' DAY 로 바꿔야 했다.
나의 최종 제출 답안:
SELECT A.id
FROM Weather A -- 오늘
JOIN Weather B -- 어제
ON A.recordDate = B.recordDate + INTERVAL '1' DAY
WHERE A.temperature > B.temperature
1. 어제의 온도와 비교 필요 → 같은 테이블 내에서 이전 날짜를 찾아야 함
2. recordDate를 기준으로 이전 날짜(recordDate - 1 day)를 찾기
=> 이 부분은 뭔가 더 나은 방법이 있었던 거 같은데 기억이 안나서 그냥 INTERVAL '1' DAY 사용
3. 현재 온도가 어제 온도보다 높은 경우
4. 결과는 id만 반환
chatGPT에게 더 간단하고 효율적이게 수정해달라고 요청한 답안:
✅ Self-Join 방식 (O(N^2)) << 내가 사용한 방법
🔍 성능 분석
1️⃣ Weather 테이블을 두 번 조회 (Self-Join 사용)
2️⃣ JOIN 조건을 만족하는 경우만 비교 (날짜 조건 + 온도 비교)
3️⃣ O(N^2) 복잡도 → 테이블 크기가 커지면 속도가 느려질 수 있음 ❌
✅ 더 효율적인 방법: LAG() 함수 사용 (O(N))
🔥 LAG() 함수를 사용하면 JOIN 없이 바로 이전 날짜의 온도를 가져올 수 있음.
SELECT id
FROM (
SELECT id, recordDate, temperature,
LAG(temperature) OVER (ORDER BY recordDate) AS prev_temp
FROM Weather
) W
WHERE W.temperature > W.prev_temp;
✅ 성능 비교
방법 | 시간 복잡도 | 설명 |
Self-Join (JOIN Weather 방식) | O(N^2) | ❌ 테이블이 클 경우 비효율적 |
LAG() 윈도우 함수 | O(N) | ✅ JOIN 없이 더 빠름 |
🔥 테이블이 크다면 LAG() 방식이 훨씬 더 빠르고 효율적입니다! 🚀
근데 위의 소스 통과를 못했음. 보니까 날짜가 연속되지 않는 경우가 있음.
그래서 결국은 JOIN으로 풀어야함.
* 데이터가 매일 연속된다면? → LAG() 사용 가능
* 날짜가 건너뛸 가능성이 있다면? → JOIN 방식 사용
위에서 말한 기억이 안났던 방법은 LAG()였음.... 챗지 통해 정리..!
🚀 LAG() 함수란? (SQL Window Function)
LAG()는 이전 행(previous row)의 값을 가져오는 윈도우 함수(Window Function)입니다.
주로 시간순 데이터(날짜 비교, 이전 값 참조 등)에서 많이 사용됩니다.
✅ 기본 문법
LAG(컬럼명, 이동할 행 수, 기본값) OVER (ORDER BY 정렬기준)
매개변수 | 설명 |
컬럼명 | 이전 값을 가져올 컬럼 |
이동할 행 수 (옵션) | 몇 행 이전 값을 가져올지 (기본값 = 1, 즉 한 행 전) |
기본값 (옵션) | 이전 값이 없을 때 반환할 기본값 (NULL이 기본) |
OVER (ORDER BY ...) | 어떤 기준으로 정렬할지 설정 |
✅ 예제 1: LAG() 기본 사용
📌 테이블: Weather
id | recordDate | temperature |
1 | 2024-02-10 | 10 |
2 | 2024-02-11 | 25 |
3 | 2024-02-12 | 20 |
4 | 2024-02-13 | 30 |
🔥 LAG()를 사용한 이전 온도 비교
SELECT id, recordDate, temperature,
LAG(temperature) OVER (ORDER BY recordDate) AS prev_temp
FROM Weather;
✅ 실행 결과
id | recordDate | temperature | prev_temp |
1 | 2024-02-10 | 10 | NULL |
2 | 2024-02-11 | 25 | 10 |
3 | 2024-02-12 | 20 | 25 |
4 | 2024-02-13 | 30 | 20 |
💡 prev_temp 열이 recordDate 기준으로 한 행 전(LAG())의 온도를 가져옴!
첫 번째 행은 이전 값이 없으므로 NULL이 출력됨. ✅
'Coding Challenges > LeetCode' 카테고리의 다른 글
[SQL50] 577. Employee Bonus (0) | 2025.02.19 |
---|---|
[Java] 28. Find the Index of the First Occurrence in a String (1) | 2025.02.14 |
[SQL50] 1581. Customer Who Visited but Did Not Make Any Transactions (0) | 2025.02.12 |
[SQL50] 1068. Product Sales Analysis I (0) | 2025.02.11 |
[Java] 27. Remove Element (0) | 2025.02.11 |