240910_TIL

J Lee·2024년 9월 10일

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

SQL 문제풀이 복습

문제 링크
4/23에 이어 2회차로 풀어본 문제.

예전에는 where 절에 bonus < 1000 or bonus is null 처럼
조건을 2개로 쪼개서 명시했는데, ifnull로 처리해주면 그럴 필요가 없다.
정답은 매우 간단하게 나옴.

SELECT e.name,
       b.bonus
FROM   employee e
       LEFT JOIN bonus b
              ON e.empid = b.empid
WHERE  Ifnull(bonus, 0) < 1000;

문제 링크
7/6에 이어 2회차로 풀어본 문제.
이번에는 CTE를 쓰지 않고 본 쿼리 한 번으로 바로 해결했고,
order by 조건에서 answer rate를 바로 계산해서 정렬해 주었다.

case when과 count를 섞어 쓰는 방법도 이제 감이 완전히 잡혔다.
까먹지 말자.

SELECT question_id AS "survey_log"
FROM   surveylog
GROUP  BY 1
ORDER  BY Count(CASE
                  WHEN action = 'answer' THEN timestamp
                end) / Count(CASE
                               WHEN action = 'show' THEN timestamp
                             end) DESC,
          question_id ASC
LIMIT  1;

문제 링크
7/7에 이어 2회차로 푼 문제.

CTE를 5개나 만들면서; 간신히 해결했던 지난번과는 다르게
오늘은 복잡하지 않게 잘 해결했던 것 같다.
시간도 훨씬 많이 단축되었고.

지난번 쿼리가 복잡해졌던 이유는

  1. recursive CTE를 써서 비어있는 월들을 다 채워주고
  2. 3달치 salary의 합을 구할 때도 window함수를 사용했기 때문

이었는데,
오늘은 그 두 개를 모두 사용하지 않고
join 조건을 잘 주었던 게 포인트였던 듯.

역시 똑같은 답을 낼 수 있다면 단순한 게 최고다.

WITH exclude
     AS (SELECT id,
                Max(month) AS "max_month"
         FROM   employee
         GROUP  BY 1),
     base
     AS (SELECT e.id,
                e.month,
                e.salary
         FROM   employee e
                LEFT JOIN exclude ex
                       ON e.id = ex.id
                          AND e.month = ex.max_month
         WHERE  ex.id IS NULL
         ORDER  BY 1,
                   2)
SELECT b1.id,
       b1.month,
       b1.salary + Ifnull(b2.salary, 0)
       + Ifnull(b3.salary, 0) AS "Salary"
FROM   base b1
       LEFT JOIN base b2
              ON b1.id = b2.id
                 AND b1.month - b2.month = 1
       LEFT JOIN base b3
              ON b2.id = b3.id
                 AND b2.month - b3.month = 1
ORDER  BY 1,
          2 DESC;
profile
기본기를 소홀히 하지 말자

0개의 댓글