본문 바로가기

SQL/HackerRank (SQL문풀)

**Hackerrank / Aggregation / Weather Observation Station 20 / MySQL **

728x90

📚문제

출처 : Hackerrank(https://www.hackerrank.com/challenges/weather-observation-station-20/problem?isFullScreen=true)


📝풀이

SELECT ROUND(AVG(LAT_N),4)
FROM (SELECT LAT_N
           , ROW_NUMBER() OVER (ORDER BY LAT_N) AS RN
           , COUNT(*) OVER() + 1 AS CNT
      FROM STATION) etc
WHERE RN BETWEEN FLOOR(CNT/2) AND CEIL(CNT/2)

 

MySQL에는 중간값을 구하는 함수가 따로 없어서 직접 구해야한다

SQL로 중위값 조건을 구하는게 까다로워서 풀이 참고..

참고링크 출처 : https://yurimyurim.tistory.com/14

 

 

📋풀이 순서

 

1. LAT_N(위도)의 오름차순으로 각 행마다 중복되지 않는 번호 부여

ROW_NUMBER() OVER (ORDER BY LAT_N) AS RN

 

2. 중간값 구하기 위해 행의 총 개수 + 1 한 CNT를 새 열로 생성

COUNT(*) OVER() + 1 AS CNT

 

3. 중간값에 해당하는 행 구하기

WHERE RN BETWEEN FLOOR(CNT/2) AND CEIL(CNT/2)

처음엔 이 부분에서 이해가 잘 되지 않았다

현재 이 문제에선 총 행의 개수가 499개(홀수)이기 때문에

(499+1) / 2 하게 되면 250 과 250사이이므로 

오름차순으로 정렬했을 때 250번째 있는 LAT_N의 값을 구하면 된다


그런데 만약 행의 개수가 500개(짝수개) 라면?

그래도 상관없이 CNT에 1을 더해주는게 맞는건가?

그럼 중간값 구하는 공식과 다른 것 아닌가 ?

라는 생각이 들었다

 

문제를 차근차근 풀어보자

공식을 따라가면

(500/2) & (500/2 +1)의 평균을 구하라고 한다

그렇다면 250번째와 251번째 LAT_N의 평균을 구하면 된다

 

그리고 다음으로 저 쿼리를 풀어보면

#만약 행의 개수가 500이라면
RN BEETWEEN FLOOR(501/2) AND CEIL(501/2)

RN이 250(=FLOOR(501/2)251(=CEIL(501/2) 사이에 있는 값

즉 , 250번째행과 251번째 행의 LAT_N의 평균값을 구하는것

따라서 공식과 동일한 값이 나오게 되는 것이다

(이런 쿼리문을 생각한게 대단..)

 

결론은 행의개수(홀수/짝수) 여부와 상관없이 올바른 값을 구하게 된다


4. 중간값에 해당하는 행들의 LAT_N(위도)값 평균 구하기

SELECT ROUND(AVG(LAT_N),4)

 

 

나중에 다시 한 번 풀어보자

728x90