241015_TIL

J Lee·2024년 10월 15일

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

SQL 문제풀이 복습

문제 링크
count와 case when을 조합하는 문제.

SELECT v.customer_id,
       Count(CASE
               WHEN transaction_id IS NULL THEN v.visit_id
             end) AS "count_no_trans"
FROM   Visits v
       LEFT JOIN Transactions t
              ON v.visit_id = t.visit_id
GROUP  BY 1
HAVING count_no_trans <> 0;

group by와 having을 조합하지 않으려면
이렇게 간단하게 풀어도 상관없다.

SELECT customer_id,
       Count(*) AS "count_no_trans"
FROM   Visits v
       LEFT JOIN Transactions t
              ON v.visit_id = t.visit_id
WHERE  t.transaction_id IS NULL
GROUP  BY 1;

문제 링크

SELECT u.name,
       Sum(amount) AS "balance"
FROM   Transactions t
       JOIN Users u
         ON t.account = u.account
GROUP  BY 1
HAVING balance > 10000;

문제 링크
1트(7/17)처럼 복잡하게 갈 필요가 없다.
어차피 1등만 뽑는 것이기 때문에 그냥 rank를 쓰든,
dense_rank를 쓰든 큰 차이가 없기도 함.

그리고 group by 뒤에 having을 써서
ranking의 결과를 바로 받아오고 싶었지만
having 절에는 window function의 연산 결과가 바로 올 수 없다.
따라서 서브쿼리로 빼 준 다음에 where절 조건으로 처리한 점도 기억해 둘 것.

SELECT customer_id,
       product_id,
       product_name
FROM   (SELECT customer_id,
               o.product_id,
               p.product_name,
               Dense_rank()
                 OVER(
                   partition BY customer_id
                   ORDER BY Count(*) DESC) AS "ranking"
        FROM   Orders o
               JOIN Products p
                 ON o.product_id = p.product_id
        GROUP  BY 1,
                  2) a
WHERE  ranking = 1;

profile
기본기를 소홀히 하지 말자

0개의 댓글