solvesql
- 전력 소비량 이동 평균 구하기
👉 문제 바로가기(solvesql)
-- 2017년 1월 1일 0시부터 2017년 2월 1일 0시까지
-- 10분 단위로 3개 발전소 전력 소비량의 1시간 범위 단순 이동 평균을 계산
-- 이동 평균 값은 소수점 셋째 자리에서 반올림
SELECT
DATETIME(measured_at, '+10 minutes') AS end_at,
ROUND((AVG(zone_quads) OVER(ORDER BY measured_at ROWS BETWEEN 5 PRECEDING AND CURRENT ROW)),2) AS zone_quads,
ROUND((AVG(zone_smir) OVER(ORDER BY measured_at ROWS BETWEEN 5 PRECEDING AND CURRENT ROW)),2) AS zone_smir,
ROUND((AVG(zone_boussafou) OVER(ORDER BY measured_at ROWS BETWEEN 5 PRECEDING AND CURRENT ROW)),2) AS zone_boussafou
FROM
power_consumptions
WHERE
strftime('%Y-%m-%d %H', measured_at) BETWEEN '2017-01-01 00' AND '2017-01-31 23'
[논리 과정]
- 이동 평균을 구하기 위해 자신을 기준으로 자신 제외 5개 이전 데이터까지 그룹핑(중앙 이동 평균이 아닌 기본 이동 평균)
- 그룹별 평균 산출하여 이동 평균 산출
- 2017-01-01 0시 ~ 2017-02-01 0시 날짜 필터링
[문제 상황]
- 처음에는 이동 평균 개념이 단순히 원하는 범위로 묶어서 평균을 산출하는 것이라고 이해해서 아래와 같이
년-월-일 시
로 시간 타입을 변경하여 그룹핑 후 평균 산출했음
-- 오답 코드 1
SELECT
MAX(measured_at) as end_at,
ROUND(AVG(zone_quads),2) AS zone_quads,
ROUND(AVG(zone_smir),2) AS zone_smir,
ROUND(AVG(zone_boussafou),2) AS zone_boussafou
FROM
power_consumptions
WHERE
strftime('%Y-%m-%d %H', measured_at) BETWEEN '2017-01-01 00' AND '2017-02-01 00'
GROUP BY
strftime('%Y-%m-%d %H', measured_at)
- 이후 이동 평균 개념을 확실하게 이해하고 산출했으나 end_at 컬럼, 이동 평균 그룹의 마지막 값을 산출하는 것에서 정답과 달랐음
-- 오답 코드 2
SELECT
MAX(measured_at) OVER(ORDER BY measured_at ROWS BETWEEN 5 PRECEDING AND CURRENT ROW) AS end_at,
ROUND((AVG(zone_quads) OVER(ORDER BY measured_at ROWS BETWEEN 5 PRECEDING AND CURRENT ROW)),2) AS zone_quads,
ROUND((AVG(zone_smir) OVER(ORDER BY measured_at ROWS BETWEEN 5 PRECEDING AND CURRENT ROW)),2) AS zone_smir,
ROUND((AVG(zone_boussafou) OVER(ORDER BY measured_at ROWS BETWEEN 5 PRECEDING AND CURRENT ROW)),2) AS zone_boussafou
FROM
power_consumptions
WHERE
strftime('%Y-%m-%d %H', measured_at) BETWEEN '2017-01-01 00' AND '2017-01-31 23'
[원인과 해결]
- 문제1의 원인 : 이동 평균은 자기 자신을 기준으로 원하는 범위만큼의 이전 데이터와의 그룹 평균을 의미한다.
- 해결 : 윈도우 절의
ROWS
문법을 사용하여 원하는 범위만큼 데이터를 지정해서 평균 산출 - 문제2의 원인 :
end_at
컬럼값으로 해당 데이터의 마지막 측정 시기(measure_at
)를 사용했는데 실제로는 이 값을 기준으로 10분뒤까지 측정한 데이터이므로 마지막 측정시기에서 10분을 더해줘야 평균을 구한 그룹의 끝나는 시간대가 된다. - 해결 :
measure_at
에 10분을 더한다.
[회고]
- 윈도우 함수의 활용법인 ROWS에 대해 배웠다.
- 데이터의 트렌드를 분석하는데 용이한 이동평균의 개념에 대해서 자세히 알게 되었다.
[핵심 개념]
- 기본 구조
ROWS BETWEEN 시작 AND 끝
시작
와끝
에 사용될 수 있는 키워드CURRENT ROW
: 현재 레코드n PRECEDING
: n개 이전 레코드에서 현재 레코드까지(이전 n개)n FOLLOWING
: 현재 레코드에서 n개 이후 레코드까지(이후 n개)UNBOUNDED PRECEDING
: 처음부터 현재 레코드까지(처음~현재)UNBOUNDED FOLLOWING
: 현재 레코드부터 마지막까지(현재~끝)PRECEDING
은 '시작'에,FOLLWING
은 '끝'에 들어갈 수 있음
'DA Study > TIL' 카테고리의 다른 글
[TIL] 리스트에서 요소 개수 카운트하기, 문자열 길이 반환 함수(CHAR_LENGTH) 활용 #SQL #MySQL (0) | 2025.03.18 |
---|---|
[TIL] 이스케이핑(ESCAPING)의 개념 및 활용 예시 #SQL #MySQL (0) | 2025.03.10 |
[TIL] CASE WHEN을 활용해 SELECT절에서 데이터 필터링하기 #SQL #SQLite #solvesql (0) | 2025.03.02 |
[TIL] 윈도우 함수 DENSE_RANK()를 활용한 TOP N 데이터 추출하기 #SQL #SQLite #solvesql (0) | 2025.02.26 |
[TIL] 집계 함수와 연산 함수를 활용한 피어슨 상관계수 구하기 #SQL #SQLite #solvesql (0) | 2025.02.25 |