다음주 월요일에 코딩테스트 일정이 잡혔다. 근 3년간 SQL을 업무에 많이 활용했지만, 코딩테스트를 접해본 경험은 없어서 걱정이 된다. 하지만!! 열심히 준비하면 좋은 결과 얻을 수 있겠지?
원래는 HackerRank에서 단순히 문제만 풀고 넘어가려고 했다.
하지만 어떤 의도를 가지고 문제 풀이를 진행했는지 정리해보는 연습도 필요할 듯 해서,
문제 풀이를 함께 정리해보려고 한다.
금, 토, 일 3일동안 빡세게 코테준비해서 좋은 결과 만들어내보자!! 화이팅!!!
문제
DIFFICULTY : Medium, SKILL : Basic, MySQL
Generate the following two result sets: |
1. Query an alphabetically ordered list of all names in OCCUPATIONS, immediately followed by the first letter of each profession as a parenthetical (i.e.: enclosed in parentheses). For example: AnActorName(A), ADoctorName(D), AProfessorName(P), and ASingerName(S). 문제해석 1) OCCUPATIONS 테이블에서 모든 이름을 알파벳 순서로 불러오기 - ORDER BY NAME ASC 2) 주어진 출력 형식에 따르기 : 직업 + 이름 + ( + 직업첫글자 + ) - CONCAT 함수 |
2. Query the number of ocurrences of each occupation in OCCUPATIONS. Sort the occurrences in ascending order, and output them in the following format: where [occupation_count] is the number of occurrences of an occupation in OCCUPATIONS and [occupation] is the lowercase occupation name. If more than one Occupation has the same [occupation_count], they should be ordered alphabetically. Note: There will be at least two entries in the table for each type of occupation. 문제해석 1) OCCUPATIONS 테이블에서 각 직업(OCCUPATION)을 가진 사람 수 COUNT 하기 - COUNT(OCCUPATION) AS OCCUPATION_COUNT 2) 직업(OCCUPATION)의 이름은 소문자로 작성하기 - LOWER 함수 3) 주어진 출력 형식에 따르기 : There are a total of + 띄어쓰기 한칸 + OCCUPATION_COUNT + OCCUPATION + s. - CONCAT 함수 |
INPUT 테이블
The OCCUPATIONS table is described as follows:
Occupation will only contain one of the following values: Doctor, Professor, Singer or Actor.
An OCCUPATIONS table that contains the following records:
OUTPUT 결과 샘플
SQL CODE
/* 1번 문제 */
SELECT CONCAT(NAME, "(", SUBSTRING(OCCUPATION, 1, 1), ")") AS NAME
FROM OCCUPATIONS
ORDER BY NAME
;
/* 2번 문제 */
SELECT CONCAT(
"There are a total of ", OCCUPATIONS_COUNT, " ", OCCUPATION, "s."
) AS NAME
FROM (
SELECT COUNT(OCCUPATION) AS OCCUPATIONS_COUNT, LOWER(OCCUPATION) AS OCCUPATION
FROM OCCUPATIONS
GROUP BY OCCUPATION
ORDER BY OCCUPATIONS_COUNT ASC, OCCUPATION ASC
) A
;
2번 출력물에 대해서 ORDER BY를 서브쿼리에서 빼서 작성해도 같은 결과가 도출된다.
이후에 테이블 크기가 증가했을 경우를 생각해서 자료조사를 해보자.
SELECT CONCAT(
"There are a total of ", OCCUPATIONS_COUNT, " ", OCCUPATION, "s."
) AS NAME
FROM (
SELECT COUNT(OCCUPATION) AS OCCUPATIONS_COUNT, LOWER(OCCUPATION) AS OCCUPATION
FROM OCCUPATIONS
GROUP BY OCCUPATION
) A
ORDER BY OCCUPATIONS_COUNT ASC, OCCUPATION ASC
;
SQL 결과
Aamina(D)
Ashley(P)
Belvet(P)
Britney(P)
Christeen(S)
Eve(A)
Jane(S)
Jennifer(A)
Jenny(S)
Julia(D)
Ketty(A)
Kristeen(S)
Maria(P)
Meera(P)
Naomi(P)
Priya(D)
Priyanka(P)
Samantha(A)
There are a total of 3 doctors.
There are a total of 4 actors.
There are a total of 4 singers.
There are a total of 7 professors.
느낀점/개선점
추가 조사 | 1. 읽기 및 실행 계획 최적화 MySQL 옵티마이저는 쿼리의 다양한 부분을 재배치하여 효율을 극대화할 수 있습니다. 이 과정에서, 하위 쿼리 결과에 대한 ORDER BY 처리는 상황에 따라 최적화될 여지가 더 많을 수 있습니다. 따라서, 2번 코드가 약간 더 효율적일 가능성이 있습니다. 2. 임시 테이블 사용 1번 코드의 경우, ORDER BY가 하위 쿼리 내부에서 수행되므로, MySQL은 이 정렬을 위해 임시 테이블을 사용할 수 있습니다. 이는 메모리 내에서 수행될 수도 있고, 필요에 따라 디스크 기반으로 전환될 수 있습니다. 반면, 2번 코드에서는 외부 쿼리의 정렬이 최종 결과에만 적용되므로, 임시 테이블 사용이 좀 더 최적화될 가능성이 있습니다. 3. 최적화의 범위 MySQL은 전체 쿼리에 대해 최적화를 수행합니다. 하위 쿼리 결과에 대한 외부 정렬(2번 코드)은 전체 쿼리 최적화 과정에서 더 넓은 범위의 최적화 전략을 고려할 수 있게 해줍니다. |
느낀점 | 처음 공부하는 거라 난이도 선택이 어렵다. DIFFICULTY는 Medium, SKILL은 Basic으로 선택했는데, 실제 문제로는 더 어려운 내용이 나올 것 같다. 어떤 분석가가 HackerRank에서 난이도는 Medium 정도에서 나오고, Hard 문제는 굳이 이렇게 까지 문제를 만들었어야 하나라는 생각이 들 정도의 문제라고 한 것을 봤다. SKILL을 Intermediate, Advanced 단계로 높여서 연습해야겠다. |
개선점 | 서브쿼리에서 필요한 데이터를 불러온 후, ORDER BY, 함수 적용을 진행해야겠다. |