본문 바로가기
프로그래밍 언어/SQL

[Hackerrank] Weather Observation Station 5

by gokite 2022. 1. 13.

자세한 문항은 아래 링크에서 확인하실 수 있습니다.

https://www.hackerrank.com/challenges/weather-observation-station-5/problem?isFullScreen=true&h_r=next-challenge&h_v=zen&h_r=next-challenge&h_v=zen&h_r=next-challenge&h_v=zen&h_r=next-challenge&h_v=zen&h_r=next-challenge&h_v=zen&h_r=next-challenge&h_v=zen&h_r=next-challenge&h_v=zen&h_r=next-challenge&h_v=zen 

 

Weather Observation Station 5 | HackerRank

Write a query to print the shortest and longest length city name along with the length of the city names.

www.hackerrank.com

 

문제 : 시티 이름이 가장 짧은 도시와 긴 도시를 추출해라

조건 :

1. 길이가 똑같다면, 알파벳 순으로 정렬

 

예시 답안:

city len(city)
abcde 5
ab 2

 

 

 

 

 

상당히 쉬운 문제긴 하나, 짚고 넘어가야할 점이 있다.

열이 아닌 행으로 결과를 도출하면서 한 번에 max, min을 볼 순 없기에

max 따로 min 따로 도출해서 행을 붙이는 식으로 가야한다.

 

그런데 이 문제에는 같은 길이에는 알파벳순으로 정렬하라는 조건이 있다.

여기서 생각해볼 점이 하나 있다.

 

 

 

UNION을 할 때에는 ORDER BY 절은 한 번만 쓸 수 있다??

우리가 ORDER BY를 테이블 당 한 번만 쓰는 것처럼, UNION을 통해 한 테이블로 만들어진 이상 한 번밖에 쓸 수 없다.

(여러 열 조건 붙는 것이 아닌 단순 ORDER BY를 여러번 작성하는 것)

 

 

우선 이점을 고려하지 않고 답안을 작성한다고 가정해보자.

 

SELECT CITY, LENTH(CITY)
FROM STATION
ORDER BY LENTH(CITY) ASC, CITY ASC LIMIT 1

UNION ALL

SELECT CITY, LENTH(CITY)
FROM STATION
ORDER BY LENTH(CITY) DESC, CITY ASC LIMIT 1

ORDER BY의 LIMIT을 사용해서 MAX, MIN의 결과 값을 추출했다.

그러나 쿼리는 돌아가지 않는다.

앞서 말했듯이, 한 테이블에는 ORDER BY가 한 번밖에 쓰일 수 없기때문이다.

 

테이블별로 정렬해서 UNION 하고 싶다면 어떻게 해야할까?

 

SELECT T1.*
FROM (
    SELECT CITY, LENGTH(CITY)
    FROM STATION
    ORDER BY LENGTH(CITY)ASC, CITY ASC LIMIT 1) AS T1
    
UNION ALL 

SELECT T2.*
FROM (
    SELECT CITY, LENGTH(CITY)
    FROM STATION
    ORDER BY LENGTH(CITY)DESC, CITY ASC LIMIT 1) AS T2

위처럼 서브쿼리로 감싸주면 해당 오류를 피할 수 있다.

여기서는 잘 작동되지만, 중요한 점이 있다.

원래 MySQL은 서브 쿼리내에서의 정렬은 적용되지 않는다.

 

SQL standard에서 정한 DB테이블 정의에서는 테이블을 채우고 있는 데이터의 ORDER는 아무런 의미가 없기때문이라고 한다. 사실 무슨 소린지는 모르겠지만, 쨌든 서브쿼리 또한 한 종류의 테이블이기때문에 작동하지 않는다.

자세한 내용은 여기!

 

서브쿼리 내에선 ORDER BY가 안된다고 했는데 왜 작동 되냐고 묻는다면..

해결 방법 중 한 가지를 이용했기 때문이다.

 

해결 방법은 2가지가 있다. 여기를 참고했다.

 

1. 서브 쿼리 내 order by 뒤에 limit 를 걸어주기

앞에서 MAX, MIN 을 뽑기 위해 limit 을 걸어놨기 때문에 서브 쿼리내 ORDER BY가 잘 작용되었다. 

limit를 걸게 되면 데이터의 순서뿐만 아니라 개수까지 제한되어 테이블의 본질적인 내용이 변화한다고 생각되어 order by가 적용된다고 한다.

 

 

2. order by를 최상위 절로 옮기기

order by를 서브 쿼리가 아닌 밖으로 빼내서 사용하라는 말인 것 같다.

 

 

 

또 다른 방법도 있다. 

 

 

1. ; 이용하기

 

SELECT CITY, LENGTH(CITY)
FROM STATION
ORDER BY LENGTH(CITY)ASC, CITY ASC LIMIT 1 ;
    
SELECT CITY, LENGTH(CITY)
FROM STATION
ORDER BY LENGTH(CITY)DESC, CITY ASC LIMIT 1 ;

단순히 ; 를 두 개만 추가해서 코드를 완성시킬 수 있다.

 

SQL 에서 세미콜론(;) 이 가지는 의미는 뭘까? 대체 언제 사용하면 되는 걸까?

명시를 안해도 무방한 세미콜론을 언제 사용해야 하나 고민이 많았다.

찾아보니 요약하면 이렇다.

"명령문을 구분해야할 때는 반드시 사용한다."

 

단일 명령문을 처리하는 경우 세미콜론은 선택사항이라고 하며 서버 고부하, 캐싱등에 발생할 수 있는 부정적인 영향을 미칠 수 있지도 않다고 한다. 역시나 자세한 내용은 여기

 

USE TABLE;
SELECT * FROM TABLE;

 

이처럼 명령문을 반드시 구분해야할 때 사용하면 된다.