본문 바로가기

TIL 통합/SQL

[HackerRank]Weather Observation Station 20 - MySQL에서 중앙값 구하기

 

https://www.hackerrank.com/challenges/weather-observation-station-20/problem?isFullScreen=true

 

Weather Observation Station 20 | HackerRank

Query the median of Northern Latitudes in STATION and round to 4 decimal places.

www.hackerrank.com

 

 

엄청 간만에 푼 중앙값 구하기 문제.

어제 치룬 모 회사의 코딩 테스트가, MySQL에서는 median이 지원 안 된다는 것을 너무나도 오랜만에 상기시켜줘서 부랴부랴 관련 문제를 풀었다. 

 

[풀이1]: 예시의 행 수가 홀수일 경우

  1.  위도를 기준으로 각 행의 번호를 부여하는 한편, 전체 행의 개수를 COUNT 함수를 통해 산출
  2. COUNT를 통해 도출한 전체 행 수를 기반으로, 전체 행 중 가운데가 되는 행의 위도를 산출
  3. WHERE절 해석: 행이 7개일 경우 '7+1/2 = 4' 이므로, 가운데인 4번째 행 출력

 

WITH ROW_N AS (
    SELECT       ID
                ,LAT_N
                ,ROW_NUMBER() OVER (ORDER BY LAT_N) AS RN
                ,COUNT(*) OVER () TTL
    FROM         STATION
)

SELECT       ROUND(LAT_N, 4)
FROM         ROW_N
WHERE        RN = (TTL+1)/2

해서 이렇게 풀 수 있는데, 위 경우는 행이 홀수인 경우에만 활용할 수 있으므로 짝수인 경우에도 사용할 수 있는 풀이가 더 정확하다고 할 수 있다.

 

 

[풀이2]: 예시의 행이 홀수, 짝수일 경우 모두 사용 가능

  1.  위도를 기준으로 각 행의 번호를 부여하는 한편, 전체 행의 개수를 COUNT 함수를 통해 산출
  2. COUNT를 통해 도출한 전체 행 수를 기반으로, 전체 행 중 가운데가 되는 행의 위도를 산출
  3. WHERE절 해석:
    1. 행이 짝수 개일 경우: 가운데 값 두개를 산출한 뒤 둘의 평균을 산출(본 게시물 아래 '중앙값 정의'참고)  
    2. 행이 홀수 개일 경우: +1을 한 뒤 반으로 나눠 가운데 값 출력
WITH ROW_N AS (
    SELECT       ID
                ,LAT_N
                ,ROW_NUMBER() OVER (ORDER BY LAT_N) AS RN
                ,COUNT(*) OVER () TTL
    FROM         STATION)
    
SELECT       ROUND(AVG(LAT_N), 4)
FROM         ROW_N
WHERE        RN IN (CASE WHEN TTL%2 = 0 THEN TTL/2 END,
                    CASE WHEN TTL%2 = 0 THEN TTL/2 + 1 END,
                    CASE WHEN TTL%2 = 1 THEN (TTL+1)/2 END)

 

 

 

 

아래는 덧. 중앙값이 단순히 가운데 값이라고 순간 오해했어서 위키피디아를 참고했다.

 

중앙값(中央-, 영어: median) 또는 중위수(中位數)는 어떤 주어진 값들을 크기의 순서대로 정렬했을 때 가장 중앙에 위치하는 값을 의미한다. 예를 들어 1, 2, 100의 세 값이 있을 때, 2가 가장 중앙에 있기 때문에 2가 중앙값이다.

값이 짝수개일 때에는 중앙값이 유일하지 않고 두 개가 될 수도 있다. 이 경우 그 두 값의 평균을 취한다. 예를 들어 1, 10, 90, 200 네 수의 중앙값은 10과 90의 평균인 50이 된다.

(출처: https://ko.wikipedia.org/wiki/%EC%A4%91%EC%95%99%EA%B0%92)