Data/SQL

[리트코드] SQL 50 - Advanced Select and Joins 문제 풀이(# 1789, # 180, # 1164)

sennysideup 2023. 10. 16. 09:24
반응형

mysql을 사용합니다.

 

# 1789 Primary Department for Each Employee

easy 난이도입니다. 쿼리 작성 자체는 어렵지 않지만 runtime이 안 좋게 나와서 다시 푼 문제입니다.

Q. 각 직원의 직원 번호와 주요 부서의 부서 번호를 표시하라.

풀이

  • key : sub query
  • 서브쿼리 : 하나의 부서에만 소속된 직원의 직원 번호를 추출합니다. 이후 where 절에서 사용합니다.
  • 시간 : 1214ms (수정 이전 1597ms)
  • 메모리 : 0b
select employee_id, department_id
from Employee
where primary_flag = 'Y' or employee_id in (
  select employee_id from Employee group by employee_id having count(department_id) = 1
)
  • 수정 이전 코드
    • union 연산 사용
select employee_id, department_id
from Employee
where primary_flag = 'Y'
union
select employee_id, department_id
from Employee
group by employee_id
having count(*) = 1

 

# 180 Consecutive Numbers

medium 난이도입니다. 여러 번 join하는 게 아직 익숙하지 않아서 정리해봅니다.

Q.연속으로 3번 나타난 모든 숫자를 출력하라 

풀이

  • key : multiple join
  • 첫 번째 join : id-1과 id가 동일한 경우를 right join → id 기준으로 right join
  • 두 번째 join : id와 id+1이 동일한 경우를 right join → id+1 기준으로 right join
  • 한 행의 num이 모두 같은 경우만 출력
  • 시간 : 836 ms
  • 메모리 : 0b
select distinct current.num as ConsecutiveNums
from Logs previous right join Logs current on previous.id-1 = current.id
right join Logs future on current.id = future.id + 1
where previous.num = current.num
and current.num = future.num

 

# 1164 Product Price at a Given Date

medium 난이도입니다. 쿼리가 길어서 개인적으로는 어렵게 느껴진 문제입니다.

Q. 2019년 8월 16일 기준, 모든 상품의 가격을 출력하라. chage_date 이전의 가격은 10이라고 가정한다.

풀이

  • key : sub query, join, if
  • 서브쿼리1 : 2019년 8월 16일 이전에 가격이 바뀐 상품의 최종 변경 일자를 저장합니다
    • 가장 안 쪽 서브쿼리
  • 서브쿼리2 : 변경일자가 서브쿼리1과 같은 경우를 필터링합니다.
    • 서브쿼리 실행 결과 : 2019년 8월 16일 이전에 가격이 바뀐 상품의 상품 id와 가격
  • join : 필터링된 데이터와 원본 데이터 join(원본 기준)
  • if : 서브쿼리 실행 결과에 값이 없는 경우, 가격 대신 10을 출력
  • 시간 : 754ms
  • 메모리 : 0b
select b.product_id as product_id, if(a.product_id is null, 10, a.new_price) as price
from (select product_id, new_price
from Products
where (product_id, change_date) in (
  select product_id, max(change_date) as change_date 
  from Products where change_date <= '2019-08-16' group by product_id)) a
right join Products b
on a.product_id = b.product_id
group by b.product_id