240913_TIL

J Lee·2024년 9월 13일

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

SQL 문제풀이 복습

문제 링크
7/4에 이어 두 번째로 푼 문제.
어차피 CTE에서 구한 값이나 본 쿼리에서 구해야 할 값 모두 스칼라이므로,
분자, 분모에 해당하는 CTE를 따로따로 만든 후에
본 쿼리에서 join해도 상관없다.

WITH total
     AS (SELECT Count(DISTINCT sender_id, send_to_id) AS "total_request"
         FROM   friendrequest),
     accept
     AS (SELECT Count(DISTINCT requester_id, accepter_id) AS "accepted"
         FROM   requestaccepted)
SELECT Ifnull(Round(accepted / total_request, 2), 0) AS "accept_rate"
FROM   total,
       accept;

문제 링크
3일, 혹은 그 이상으로 날짜가 연속되고
people의 숫자가 100 이상인 데이터만 추출하는 문제.

지난번(7/3)과 동일하게
CTE 안에서 100명을 넘어가는 데이터를 뽑음과 동시에
그루핑의 기준이 될 컬럼(temp)을 만들어 주고,
본 쿼리에서는 temp가 3을 넘어가는 경우만 뽑아주면 완성이다.

WITH result
     AS (SELECT id,
                visit_date,
                people,
                id - Row_number()
                       OVER(
                         ORDER BY visit_date) AS "temp"
         FROM   stadium
         WHERE  people >= 100)
SELECT id,
       visit_date,
       people
FROM   result
WHERE  temp IN (SELECT temp
                FROM   result
                GROUP  BY 1
                HAVING Count(*) >= 3);

문제 링크
그렇게 어렵지 않게 풀 수 있는 문제.
이 문제는 오늘이 3번째 풀이였는데,
첫 번째부터 오늘까지 오는 동안
풀이 방식에도 조금씩이나마 발전이 있었던 것 같다.

  • 1회차 : CTE가 아니라 인라인뷰 서브쿼리로 해결 + 미리 친구 수를 group by로 구해놓고 본 쿼리에서는 sum을 해 줌
  • 2회차 : CTE 사용 + 미리 친구 수를 group by로 구해놓고 본 쿼리에서는 sum을 해 줌
  • 3회차(오늘) : CTE 사용 + 친구 수를 따로 구하지 않고 우선 CTE에서는 전체 친구 결과만 보여준 다음 본 쿼리에서 친구 수를 구함
WITH cte
AS
  (
         SELECT requester_id AS "id",
                accepter_id
         FROM   requestaccepted
         UNION ALL
         SELECT   accepter_id,
                  requester_id
         FROM     requestaccepted
         ORDER BY 1)
  SELECT   id,
           count(*) AS "num"
  FROM     cte
  GROUP BY 1
  ORDER BY 2 DESC
  LIMIT    1;

잠을 못 자서 헤롱대는 상태에서도
세 문제 정도 해결하는 건 가능해진 상태가 된 것 같다.
SQL은 계속 이렇게 감을 잃지 않을 정도로만 유지해 주자.

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

0개의 댓글