241104_TIL

J Lee·2024년 11월 4일
0

아무리 사소하더라도 배움이 없는 날은 없다.

SQL 문제풀이 복습


Leetcode

문제 링크
이 문제는 잠깐 홀딩.
풀릴듯 말듯 한데 생각이 잘 안 떠오른다ㅜ

문제 링크
salary가 30000 미만인 직원들 중
manager가 퇴사하고 없는 직원의 id를 출력하는 문제.
이 문제에서 주의해야 할 건 서브쿼리 안에서
manager_id가 null이 아니라는 조건을 주어야 한다는 것이다.

매니저가 있었는데 (즉, manager_id가 null은 아닌데) 퇴사한 것과
애초부터 매니저가 없었던 (즉, manager_id가 null인) 경우는 다르므로.

서브쿼리를 자연스럽게 쓰긴 했는데
1트(5/12) 때처럼 꼭 서브쿼리를 쓰지 않아도
where절 안에서 조건으로 처리해도 무방.

SELECT a.employee_id
FROM   (SELECT employee_id,
               manager_id
        FROM   Employees
        WHERE  salary < 30000
               AND manager_id IS NOT NULL) a
       LEFT JOIN Employees e
              ON a.manager_id = e.employee_id
WHERE  e.employee_id IS NULL
ORDER  BY 1;

문제 링크
1트(9/2) 때는 window함수를 쓰지 않고
join한 이후에 바로 max(count)와 min(score)를 적용했다.
오늘은 rank를 써서 count는 내림차순, score는 오름차순으로 정렬한 뒤
그 값이 1인 경우만 서브쿼리에서 뽑아오는 방식을 택했다.

뭐가 됐든 대세에 큰 지장은 없는 풀이인데,
보면 볼수록 Leetcode의 문제 만듦새가 정교하다고 느끼는 부분.

  1. join을 할 때 반드시 공통 키가 있어야 하는 것은 아니고
  2. join의 결과를 (집계함수든, window함수든 간에) 끌어다 쓰려면 cte나 서브쿼리 처리해야 한다

는 것을 알아야 해결이 가능한 문제다.
capacity와 student_count가 정확히 일치하는 경우도
있을 수 있기 때문에 join의 조건에서 등호를 빼먹으면
오답이 뜨게끔 테스트 케이스를 만들어 놓은 점도 그렇고.
Leetcode는 누가 어떻게 만들고 있는 걸까🤔

SELECT school_id,
       IFNULL(score, -1) AS "score"
FROM   (SELECT school_id,
               score,
               RANK()
                 OVER(
                   PARTITION BY school_id
                   ORDER BY student_count DESC, score ASC) AS "ranking"
        FROM   Schools s
               LEFT JOIN Exam e
                      ON s.capacity >= student_count) a
WHERE  ranking = 1
ORDER  BY 1; 
profile
기본기를 소홀히 하지 말자

0개의 댓글

관련 채용 정보