본문 바로가기

알고리즘

[HackerRank] MySQL 중앙값, Median 구하기

반응형

 

 

Weather Observation Station 20 | HackerRank

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

www.hackerrank.com

 

A median is defined as a number separating the higher half of a data set from the lower half. Query the median of the Northern Latitudes (LAT_N) from STATION and round your answer to 4 decimal places.

중앙값은 데이터 세트의 상위 절반과 하위 절반을 구분하는 숫자로 정의됩니다. STATION에서 북위도 (LAT_N)의 중앙값을 쿼리하고 답을 소수점 이하 4 자릿수로 반올림합니다.

Input Format

The STATION table is described as follows:

STATION 테이블은 다음과 같이 설명됩니다.

where LAT_N is the northern latitude and LONG_W is the western longitude.

여기서 LAT_N은 북쪽 위도이고 LONG_W는 서쪽 경도입니다.

풀이

중앙값을 구하는 아이디어는 다음과 같습니다.

1. LAT_N을 기준으로 데이터를 정렬
2. limit을 이용하여 절반으로 자른다.
3. LAT_N을 기준으로 반대로 정렬
4. limit 1으로 중앙값 도출~!

문제는 limit에 변수를 집어넣을 수 없다는 점입니다... 데이터를 절반으로 나누려면 먼저 데이터의 수를 알아야 가변적으로 대응을 할텐데 변수를 넣을 수 없다면 난감하겠죠? 이 문제는 prepare와 execute를 이용하여 해결할 수 있습니다.

또한, prepare를 사용하면 다음과 같은 이점이 있어, 서버 사이드에서 구문을 미리 준비하여 사용한다고 합니다.

  • 명령문이 실행될 때마다 구문 분석을위한 오버 헤드가 적습니다. 일반적으로 데이터베이스 애플리케이션은 쿼리 및 삭제의 경우 WHERE, 업데이트의 경우 SET, 삽입의 경우 VALUES와 같은 절의 리터럴 또는 변수 값만 변경하여 거의 동일한 명령문을 대량으로 처리합니다.
  • SQL 주입 공격으로부터 보호합니다. 매개 변수 값에는 이스케이프 처리되지 않은 SQL 따옴표 및 구분 문자가 포함될 수 있습니다.

https://dev.mysql.com/doc/refman/8.0/en/sql-prepared-statements.html

 

MySQL :: MySQL 8.0 Reference Manual :: 13.5 Prepared Statements

13.5 Prepared Statements MySQL 8.0 provides support for server-side prepared statements. This support takes advantage of the efficient client/server binary protocol. Using prepared statements with placeholders for parameter values has the following benefi

dev.mysql.com

먼저 mid에 해당하는 값을 변수에 집어넣습니다. 이때 SELECT 절을 감싸는 괄호와 문장을 끝마치는 세미콜론을 잊지 말아주세요~!

SET @mid = (SELECT ROUND(COUNT(LAT_N)/2) FROM STATION);

다음으로 구문을 준비합니다. 정렬해서 (변수로) 절반 자르고, 반대로 정렬해서 1개 자르고, 반올림. prepare 구문은 문자열로 이루어지기 때문에 구문을 미리 테스트 해보는 편이 실수를 줄이기 좋을 것 같습니다.

PREPARE medianQuery FROM
    'SELECT ROUND(t.LAT_N, 4) FROM
    (SELECT LAT_N FROM STATION ORDER BY LAT_N LIMIT ?) AS t
    ORDER BY t.LAT_N DESC
    LIMIT 1';

변수와 구문 모두 준비되었으니 execute를 이용하여 실행해줍니다.

EXECUTE medianQuery USING @mid; 
반응형