[HackerRank] The Report

주연·2023년 2월 19일
0

SQL 문제 풀이

목록 보기
13/29
post-thumbnail

230219

문제

https://www.hackerrank.com/challenges/the-report/problem?h_r=internal-search

  • Students와 Grades 테이블 2개로 구성
  • Marks에 해당하는 Grade 찾기
  • Grade를 기준으로,
    8보다 크거나 같으면 grade 순으로 내림차순, name으로 오름차순
    8보다 작으면 name은 NULL로, grade 순으로 내림차순, marks으로 오름차순

풀이

먼저 생각한 것은 between을 써야할 것 같은데 where에 쓰자니 형태가 안 맞고 그럼 join에 써야하나? 쓸 수 있나 하고 구글링을 해봤다.
그 결과 사용 가능함을 알게 되었다.

WITH higher AS (
    SELECT s.Name, g.Grade, s.Marks
    FROM Students s
        INNER JOIN Grades g ON s.Marks BETWEEN g.Min_Mark AND g.Max_Mark
    WHERE Grade >= 8
    ORDER BY g.Grade DESC, s.Name
), lower AS (
    SELECT (CASE WHEN Grade < 8 THEN s.Name = NULL END) Name, g.Grade, s.Marks
    FROM Students s
        INNER JOIN Grades g ON s.Marks BETWEEN g.Min_Mark AND g.Max_Mark
    WHERE Grade < 8
    ORDER BY g.Grade DESC, s.Marks
)

SELECT *
FROM higher 
UNION ALL
SELECT *
FROM lower

grade별로 따로 나눠 테이블 만들고 합칠 생각이었으나 union을 쓰는 순간 정렬이 없어진다. 즉 문제에서 요구하는 정렬 방식을 적용할 수 없었다.
그래서 다른 방법을 고민해보았고,
order by에서 조건문을 쓸 수 있음을 알게 되어 해봤다.

SELECT (CASE WHEN g.Grade < 8 THEN s.Name = NULL ELSE s.Name END) Name
		, g.Grade
        , s.Marks
FROM Students s
    INNER JOIN Grades g ON s.Marks BETWEEN g.Min_Mark AND g.Max_Mark
ORDER BY g.Grade DESC,
        CASE WHEN g.Grade < 8 THEN s.Marks
             WHEN g.Grade >= 8 THEN s.Name END

휴..맞았다

  • 다른 사람 문제 풀이 확인(수업 확인)
SELECT CASE WHEN g.Grade < 8 THEN NULL ELSE s.Name END Name
		, g.Grade
        , s.Marks
FROM Students s
    INNER JOIN Grades g ON s.Marks BETWEEN g.Min_Mark AND g.Max_Mark
ORDER BY g.Grade DESC, name, s.Marks

어...? 정렬 그냥 해도 되는 거였구나 저것때문에 고민 엄청했는데.. 생각이 짧았다
정렬써도 앞 정렬조건 먼저 진행된다는 것 기억하자
또한 NULL은 오름차순일 때 맨 마지막에 위치한다는 것 기억하자!!!

profile
공부 기록

0개의 댓글