working_helen
[코테 연습] HackerRank 코딩테스트 연습 Easy & Medium 본문
HackerRank 코딩테스트 연습 Easy & Medium
Weather Observation Station 5
: Query the two cities in STATION with the shortest and longest CITY names, as well as their respective lengths (i.e.: number of characters in the name). If there is more than one smallest or largest city, choose the one that comes first when ordered alphabetically.

풀이 1
- 정렬만을 가지고 쉽게 record를 얻기 위해
LENGTH(CITY) 오름차순 정렬했을 때, 내림차순 정렬했을 때, 따로따로 진행
- ROW_NUMBER(), RANK() 다 가능 / DENSE_RANK()는 불가능
WITH TBL AS (
SELECT CITY, LENGTH(CITY) AS LEN,
ROW_NUMBER() OVER (ORDER BY LENGTH(CITY), CITY) AS RN_MIN,
ROW_NUMBER() OVER (ORDER BY LENGTH(CITY) DESC, CITY) AS RN_MAX
FROM STATION
)
SELECT CITY, LEN
FROM TBL
WHERE RN_MIN = 1 OR RN_MAX = 1;
풀이 2
- 원하는 정보 하나씩 추출한 후 UNION하기
- where절에서 rownum을 사용하기 위해 서브쿼리로 묶기
- 절대적인 행 번호가 아닌 가상의 번호이므로 '<' 연산만 가능
(
SELECT CITY, LENGTH(CITY) AS LEN
FROM (
SELECT CITY
FROM STATION
ORDER BY LENGTH(CITY), CITY
)
WHERE ROWNUM = 1
) UNION (
SELECT CITY, LENGTH(CITY) AS LEN
FROM (
SELECT CITY
FROM STATION
ORDER BY LENGTH(CITY) DESC, CITY
)
WHERE ROWNUM = 1
);
Draw The Triangle 1
: P(R) represents a pattern drawn by Julia in R rows. The following pattern represents P(5). Write a query to print the pattern P(20).
* * * * *
* * * *
* * *
* *
*
풀이
- 테이블 없이 SQL로 결과를 리턴하고 싶을 때, FROM DUAL 사용
- RPAD(대상 문자열, n, 추가 문자열)
- '대상 문자열'의 오른쪽에, '추가 문자열'을 연결해서, 길이가 n까지 리턴
- 이때 '추가 문자열' 연결로 길이가 n 이상이 되면, 연결 후 n까지만 잘려서 리턴
> START WITH 없이 CONNECT BY
→ 특정한 행을 root로 지정하지 않고 가능한 가능한 모든 경로를 탐색하는 계층형 쿼리
- Oracle이 알아서 DUAL 테이블에서 LEVEL = 1부터 시작해서 계층형 탐색 진행
- LEVEL 20까지만 탐색하기 위해, 탐색에서 연결 조건을 지정하는 CONNECT BY를 사용
SELECT RPAD('* ', 2*LEVEL-1, '* ') AS PATTERN
FROM DUAL
CONNECT BY LEVEL <= 20
ORDER BY LEVEL DESC;
The PADS
: 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), ProfessorName(P), and ASingerName(S). Query the number of ocurrences of each occupation in OCCUPATIONS. Sort the occurrences in ascending order, and output them in the following format: "There are a total of [occupation_count] [occupation]s."


> Oracle에서 문자열 연결
- CONCAT(문자열1, 문자열2) : 2개의 문자열을 연결할 때 사용
- 문자열1 || 문자열2 || 문자열3 || ... : 3개 이상의 문자열을 연결할 때 사용
- UNION 사용시 개별 쿼리 내에서 ORDER BY를 사용할 수 없음!
→ 정렬에 사용할 칼럼을 서브쿼리 내에서 별도로 리턴하기
- 여러 개의 쿼리 결과를 한번에 리턴하는 경우
→ 쿼리 순서대로 출력될 수 있도록 쿼리의 순서를 의미하는 칼럼을 서브쿼리 내에서 리턴하기
SELECT OUTPUT
FROM(
SELECT NAME || '(' || (CASE WHEN OCCUPATION = 'Actor' THEN 'A'
WHEN OCCUPATION = 'Doctor' THEN 'D'
WHEN OCCUPATION = 'Professor' THEN 'P'
ELSE 'S' END) || ')' AS OUTPUT,
NAME AS FIRST_ORDER, NULL AS SEC_ORDER, '1' AS QUEST_ORDER
FROM OCCUPATIONS
UNION
SELECT 'There are a total of ' || COUNT(*) || ' ' || LOWER(OCCUPATION) || 's.' AS OUTPUT,
TO_CHAR(COUNT(*)) AS FIRST_ORDER, OCCUPATION AS SEC_ORDER, '2' AS QUEST_ORDER
FROM OCCUPATIONS
GROUP BY OCCUPATION
) TMP
ORDER BY QUEST_ORDER, FIRST_ORDER, SEC_ORDER;
The Report
: You are given two tables: Students and Grades. Generate a report containing three columns: Name, Grade and Mark. Ketty doesn't want the NAMES of those students who received a grade lower than 8. The report must be in descending order by grade. If there is more than one student with the same grade (8-10) assigned to them, order those particular students by their name alphabetically. Finally, if the grade is lower than 8, use "NULL" as their name and list them by their grades in descending order.

풀이
- 원하는 정보 하나씩 추출한 후 UNION하기
- UNION 사용시 개별 쿼리 내에서 ORDER BY를 사용할 수 없음!
→ 정렬에 사용할 칼럼을 서브쿼리 내에서 별도로 리턴하기 (여기서는 GRADE, NAME으로 정렬)
- ON절 조건을 사용해 JOIN 방법에 관한 조건을 설정
JOIN을 할 때 G의 MIN_MARK와 MAX_MARK 값을 S의 MAKRS 값과 비교하도록
WITH TMP AS (
SELECT NAME, GRADE, MARKS
FROM STUDENTS S JOIN GRADES G
ON S.MARKS BETWEEN G.MIN_MARK AND G.MAX_MARK
)
SELECT * FROM TMP
WHERE GRADE > 7
UNION
SELECT NULL AS NAME, GRADE, MARKS FROM TMP
WHERE GRADE <= 7
ORDER BY 2 DESC, 1;
Binary Tree Nodes
: You are given a table, BST, containing two columns: N and P, where N represents the value of a node in Binary Tree, and P is the parent of N. Write a query to find the node type of Binary Tree ordered by the value of the node.

> col값 IN (비교값1, 비교값 2, 비교값3, ...)
- IN 은 col값을 리스트 내에 있는 모든 비교값과 '=' 연산 + 'or' 연결
'='를 만족하는 비교값이 적어도 하나 있으면 True를 리턴
- 비교값에 NULL이 있더라도 True를 리턴하는 비교값이 하나라도 있으면 True를 리턴하므로
즉 IN 함수는 비교값 리스트에 NULL이 있든 없든 영향을 받지 않음
> col값 NOT IN (비교값1, 비교값 2, 비교값3, ...)
- NOT IN은 col값을 리스트 내에 있는 모든 비교값과 '=' 연산 + 'and' 연결
'='를 만족하지 않는 비교값이 하나라도 있으면 True를 리턴
- 비교값에 NULL이 있으면 col값이 무엇이든 NULL과의 '=' 연산은 unknown으로 False 취급되므로
실제로 col값이 리스트 내에 없어 True가 나와야하지만 NULL과의 비교로 인해 Fasle가 출력될 수 있음
- 정확한 비교를 비교해서 NOT IN 함수는 비교값 리스트에 NULL이 없어야 함
NOT NULL로 제거, NOT EXISTS로 대체 등 방법 이용
풀이 1 : IN 사용
select N, case when P is null then 'Root'
when N in (select distinct P from BST) then 'Inner'
else 'Leaf' end
from BST
order by 1;
풀이 2 : NOT IN 사용
- 비교값 리스트에서 not null 조건 넣어서 NULL 제거해야 함
select N, case when P is null then 'Root'
when N not in (select distinct P from BST where P is not null) then 'Leaf'
else 'Inner' end
from BST
order by 1;
'외부 수업 > SQL 스터디' 카테고리의 다른 글
| [코테 연습] HackerRank 코딩테스트 연습 Medium & Hard (1) | 2025.07.13 |
|---|---|
| [코테 연습] Leetcode 코딩테스트 연습 Hard (2) | 2025.06.27 |
| [코테 연습] Leetcode 코딩테스트 연습 MySQL Med. ~ Hard (2) | 2025.06.09 |
| [코테 연습] Leetcode 코딩테스트 연습 MySQL Med. (0) | 2025.06.02 |
| [코테 연습] Leetcode 코딩테스트 연습 MySQL Med. (0) | 2025.05.26 |