Lv2. 연도 별 평균 미세먼지 농도 조회하기; GROUP BY, AVG
https://school.programmers.co.kr/learn/courses/30/lessons/284530
1. Problem
전국의 월별 미세먼지 측정 데이터에서 '수원' 지역의 연도별 평균 농도를 산출해야 한다. 소수점 반올림 조건과 특수문자가 포함된 컬럼명 부여, 그리고 날짜 데이터에서 연도 정보를 추출하는 복합적인 SQL 스킬이 요구된다.
2. Solution: 집계 함수와 포맷팅의 조화
YEAR() 함수로 연도를 추출하고, AVG와 ROUND를 중첩하여 요구사항에 맞는 수치를 계산한다.
3. Takeaway: 실전에서 점수를 깎는 3대 함정
- 특수문자 별칭(Alias)의 엄격함: SQL에서 마침표(.)는 보통 테이블.컬럼 형식을 의미하는 예약어이다. 따라서 PM2.5라는 이름을 그대로 쓰면 엔진이 구조적 오류로 인식할 수 있다. **따옴표(" " 또는 ' ')**로 감싸 '문자열 별칭'임을 명시하는 습관이 중요하다.
- 반올림의 논리적 위치: ROUND(AVG(값), 2)는 전체 평균을 낸 후 마지막에 다듬는 방식이다. 반면 행마다 반올림을 먼저 수행하면 오차가 누적될 수 있으므로, 집계 후 가공하는 순서를 지켜야 한다.
- 날짜 추출과 그룹화의 일치: SELECT 절에서 연도를 추출했다면, GROUP BY 절에서도 동일하게 연도 단위로 묶어줘야 한다. 이는 시계열 데이터를 범주형 데이터로 변환하여 분석하는 가장 기초적이면서도 강력한 도구이다.
AIR_POLLUTION 테이블은 전국의 월별 미세먼지 정보를 담은 테이블입니다. AIR_POLLUTION 테이블의 구조는 다음과 같으며 LOCATION1, LOCATION2, YM, PM_VAL1, PM_VAL2은 각각 지역구분1, 지역구분2, 측정일, 미세먼지 오염도, 초미세먼지 오염도를 의미합니다.
Column nameTypeNullable
| LOCATION1 | VARCHAR | FALSE |
| LOCATION2 | VARCHAR | FALSE |
| YM | DATE | FALSE |
| PM_VAL1 | NUMBER | FLASE |
| PM_VAL2 | NUMBER | FLASE |
문제
AIR_POLLUTION 테이블에서 수원 지역의 연도 별 평균 미세먼지 오염도와 평균 초미세먼지 오염도를 조회하는 SQL문을 작성해주세요. 이때, 평균 미세먼지 오염도와 평균 초미세먼지 오염도의 컬럼명은 각각 PM10, PM2.5로 해 주시고, 값은 소수 셋째 자리에서 반올림해주세요.
결과는 연도를 기준으로 오름차순 정렬해주세요.
예시
AIR_POLLUTION 테이블이 다음과 같을 때
| LOCATION1 | LOCATION2 | YM | PM_VAL1 | PM_VAL2 |
| 경기도 | 수원 | 2018-01-01 | 48 | 27 |
| 경기도 | 수원 | 2018-02-01 | 51 | 30 |
| 경기도 | 수원 | 2018-03-01 | 52 | 21 |
| 경기도 | 수원 | 2018-04-01 | 52 | 20 |
| 경기도 | 수원 | 2018-05-01 | 45 | 19 |
| 경기도 | 수원 | 2018-06-01 | 39 | 17 |
| 경기도 | 수원 | 2018-07-01 | 27 | 15 |
| 경기도 | 수원 | 2018-08-01 | 26 | 16 |
| 경기도 | 수원 | 2018-09-01 | 21 | 12 |
| 경기도 | 수원 | 2018-10-01 | 31 | 18 |
| 경기도 | 수원 | 2018-11-01 | 56 | 21 |
| 경기도 | 수원 | 2018-12-01 | 44 | 27 |
| 서울시 | 노원 | 2018-11-01 | 25 | 45 |
| 경기도 | 용인 | 2018-02-01 | 14 | 21 |
SQL을 실행하면 다음과 같이 출력되어야 합니다.
| YEAR | PM10 | PM2.5 |
| 2018 | 41 | 20.25 |
1. 정답 코드
SELECT YEAR(YM) AS YEAR,
ROUND(AVG(PM_VAL1),2) AS PM10,
ROUND(AVG(PM_VAL2),2) AS 'PM2.5'
FROM AIR_POLLUTION
WHERE LOCATION2 = '수원'
GROUP BY YEAR(YM)
ORDER BY 1;
2. 나의 오답
SELECT YEAR(YM) AS YEAR # , 콤마 빼먹음
ROUND(AVG(PM_VAL1),2) AS PM10,
ROUND(AVG(PM_VAL2),2) AS PM2.5 # 숫자 사이 . 점이 있는 경우 따옴표로 묶어줘야함
FROM AIR_POLUTION # 테이블 명 오타 LL
WHERE LOCATION2 = '수원'
GROUP BY YEAR(YM)
ORDER BY YEAR(YM);
놓치기 쉬운 함정 (Checklist)
- 테이블명 오타 주의: AIR_POLLUTION인데 AIR_POLUTION으로 적지 않았는지? (실제 시험에서 가장 허무한 감점 요인!)
- 특수문자가 포함된 Alias: 컬럼명에 .이 들어간 PM2.5 같은 경우, DB 엔진에 따라 에러를 뱉을 수 있습니다. 쌍따옴표(" ")로 감싸주는 습관이 안전합니다.
- 반올림 자릿수: "소수 셋째 자리에서 반올림" 하라는 말은 **"둘째 자리까지 보여달라"**는 뜻입니다. ROUND(값, 2)가 정답입니다.
핵심 개념 정리
① 날짜 함수 활용 (YEAR)
YM 컬럼이 2018-01-01 형태의 DATE 타입일 때, 이를 연도별로 묶기 위해서는 YEAR() 함수를 사용해 숫자 2018로 변환하는 과정이 필요합니다.
② 집계 함수와 산술 연산의 순서
ROUND(AVG(컬럼), 2) 처럼 평균을 먼저 구한 뒤 그 결과를 반올림해야 합니다.
③ 정렬 (ORDER BY)
SELECT 절에서 정의한 별칭(YEAR)을 ORDER BY 절에서 그대로 사용할 수 있습니다. (MySQL 기준)
테이블 이름이나 특수문자 별칭 처리 같은 디테일한 규칙을 한 번 더 점검하자!
사소한 오타는 실력이 아니라 습관의 문제다. 자신감을 갖되, 제출 전 한 번만 더 째려보자!"