[4.4.TIL] SQL의 화려한 뒤통수

Brave_ Oh·2025년 4월 4일
1

데이터_정규캠프

목록 보기
25/25
post-thumbnail

돌아온 SQL은 날 후두려팼다

오늘은 QCC를 보았다. 난 2주 동안 SQL을 사실상 놓아버린 상태였는데, 결과는 결국 난투전이었다. 4개 문제 중 2개 문제를 맞추는데는 성공했지만 그것조차 반쪽짜리였다고 난 생각한다.

너무 버벅댔다

처음 4개 문제를 받았을 때, 예전처럼 빠르게 접근하는 기민함이 사라졌다고 느꼈다. 어...어.... 하면서 문제를 읽고 있는 나를 보면서, SQL 쿼리 작성 능력을 빠르게 키운 만큼, 놓치면 빠르게 사라진다는 것도 깨달았다.

select b.unique_logins, count(b.employee_id) employee_count
from
(
    select a.employee_id, count(a.login_result) as unique_logins
    from
      (
          select employee_id, login_id, login_time, login_result
          from logins
          where month(login_time) >=7 and month(login_time) <= 9 and login_result = 'SUCCESS'
      ) as a
    join
      (
          select  *
          from employees
      ) as b
    on a.employee_id = b.employee_id
    group by a.employee_id
) as b
group by b.unique_logins

이 문제에서 핵심은 계산 함수값을 뽑아낸 뒤에, 그 결과값을 다시 기준으로 삼아서 새로운 계산 함수를 사용해야 한다는 점이었다. 처음에는 count() 함수로 group을 걸어줘야 하나 했지만, 그럴 경우 그냥 전부 샌 값 하나만 잡기 때문에 갈피를 잡지 못해 시간을 너무 잡아먹었다.

그래서 이렇게도 가능한가? 싶었던 방법을 시도했었는데, 그것이 문제의 해답이었던 셈이다. 또한 month()를 사용해 달을 구한 것 역시 한계가 있었는데, 해당 자료는 2023년 3분기 자료이기 때문에 상관이 없지만, 만약 1, 2년 자료로 구했다면 다른 해의 월까지 같이 집계가 되었을 것이므로, 틀린 답이 도출되었을 것이다.

튜터님은 with를 사용해서 좀 더 깔끔하게 문제를 푸시는 것 같은데, 역시 서브쿼리의 사나이 오대준 답게 아주 너저분하게 풀었다.

select employee_id, name, salary
from 
    (
      select employee_id, name, salary, DENSE_RANK() over (order by salary DESC) wage_rank
      from employee_salary  
    ) as a
where a.wage_rank = 3
order by employee_id asc

이 문제의 경우, 코드 자체는 어렵지 않았지만 window func 중 하나인 rank 시리즈, 그 중에서도 dens_rank를 사용해야 했다. 처음에 rank를 사용했을 때 답이 나오지 않았는데, rank는 동일한 수치와 순위가 나왔을 경우 그만큼 순위를 건너뛰기 때문이다. 따라서 이를 해결하기 위해선 동일한 순위도 매겨주고, 그러면서 다른 순위를 건너뛰지 않는 dens_rank를 사용하는 것이 핵심이었다.

3번 문제는 풀지 못했기 때문에 강의를 보고 주말에 재도전을 해볼 생각이다.

select b.user_id, a.channel
from 
    (
      select *
      from ad_attribution
      where converted = '1'	
    ) as a 
    join
    (
      select session_id, user_id, created_at, rank() over(partition by user_id order by created_at) as CR
      from user_sessions
    ) as b
    on a.session_id = b.session_id
where CR = 1
order by user_id asc

4번 문제는 도전 문제였으며, 나는 튜터님과 다른 방식으로 문제를 풀어버렸다. 가장 처음 세션을 시작한 날짜를 뽑아내야 했으며, 모든 사람이 세션에 접속한 날짜와 횟수가 다르다는 점이 난관이었다. 그래서 먼저 뽑아야 하는 조건, 즉. 세션 접속에 구매 전환이 일어난 고객들을 솎아냈으며, 유저 세션에서 조건을 rank 함수를 걸어, 각자의 세션 시작 날짜에 순위를 매겨줬다. 그리고 그 순위가 1인 회원들만 뽑으면 완료가 된다.

근데 하나 틀린 건 대체 뭘까. 언뜻 튜터님과 답이 거의 비슷해서 맞춘 줄 알았는데, 흠....

profile
데이터 분석 애송이의 유쾌한 반란

0개의 댓글

관련 채용 정보