stock_code ASC, streak_start_date ASCQ8 출석 도장 트릭 + 어제와 비교. 두 개를 겹쳐 쓰는 문제다. 이게 풀리면 시계열 문제는 거의 다 풀린다.
| 줄번호 | 날 | 종가 | 어제 | 올랐나 | 오른날 줄번호 | 차이 |
|---|---|---|---|---|---|---|
| 1 | 1일 | 100 | - | - | ||
| 2 | 2일 | 110 | 100 | O | 1 | 1 |
| 3 | 3일 | 120 | 110 | O | 2 | 1 |
| 4 | 4일 | 130 | 120 | O | 3 | 1 |
| 5 | 5일 | 125 | 130 | X | ||
| 6 | 6일 | 130 | 125 | O | 4 | 2 |
차이 1 이 세 개 → 2일~4일이 한 덩어리(3일 연속). 6일은 차이가 2 라서 다른 덩어리.
오늘 > 어제).> 지 >= 가 아니다.묻는 것 · LAG 로 상승일을 가리고, 그 위에 gaps and islands 를 한 번 더 얹는다. 두 패턴을 포개는 문제. 이게 풀리면 시계열 문제는 거의 다 풀린다.
ROW_NUMBER() OVER (PARTITION BY stock_code ORDER BY trade_date) AS rn. 이게 '몇 번째 거래일인가' 다. 날짜가 아니라 이 번호가 기준이 된다.LAG(close_price) OVER (PARTITION BY stock_code ORDER BY trade_date) 로 전 거래일 종가를 끌어온다.WHERE prev IS NOT NULL AND close_price > prev 로 상승일만 남긴다.rn − 새 행번호 → 연속 상승 구간마다 같은 값.MIN/MAX/COUNT, HAVING COUNT(*) >= 3.WITH p AS (
SELECT stock_code, trade_date, close_price,
ROW_NUMBER() OVER (PARTITION BY stock_code ORDER BY trade_date) AS rn,
LAG(close_price) OVER (PARTITION BY stock_code ORDER BY trade_date) AS prev
FROM stock_daily_prices
),
u AS (
SELECT stock_code, trade_date,
rn - ROW_NUMBER() OVER (PARTITION BY stock_code ORDER BY trade_date) AS grp
FROM p
WHERE prev IS NOT NULL AND close_price > prev
)
SELECT stock_code,
MIN(trade_date) AS streak_start_date,
MAX(trade_date) AS streak_end_date,
COUNT(*) AS streak_days
FROM u
GROUP BY stock_code, grp
HAVING COUNT(*) >= 3
ORDER BY stock_code, streak_start_date;DATEDIFF 대신 행 번호를 일련번호로 써야 한다. 「끊김복귀」·「동점」 데이터셋이 이걸 잡는다.close_price > NULL 은 NULL(거짓 취급)이라 대부분 자동으로 빠지지만, 명시하는 편이 안전하고 읽기도 낫다.COUNT(*) + 1 이고 시작일도 하루 앞이 된다. 문제를 다시 읽어라 — 출제자가 어느 쪽을 묻는지가 갈린다.“N일 연속 하락”이면 부등호만 뒤집는다. “최장 구간 하나만”이면 마지막에 ROW_NUMBER() OVER (PARTITION BY stock_code ORDER BY COUNT(*) DESC) 로 1등만. “연속 상승률”이면 구간 양 끝 종가가 필요하므로 FIRST_VALUE/LAST_VALUE 를 쓰거나 시작일 하루 전 종가를 따로 끌어온다.