240507_TIL

J Lee·2024년 5월 7일
0

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

SQL코드카타 102번
SQL코드카타 103번
SQL코드카타 104번
SQL코드카타 105번
SQL코드카타 106번

오늘은 코드카타를 5문제 진행했다. 과제나 팀프로젝트가 있는 것도 아니고 100번대 들어오니 이상하게 쉬운 문제들만 계속 나오고 있어서 굳이 하나만 풀 이유가 없어진 듯. (102~104번은 기초적인 문법 문제라 생각 과정을 포스팅에 길게 남기지 않았다.)

105번은 그래도 한 번은 생각할 거리가 있는데, having절에도 스칼라 서브쿼리처럼 '전체 상품 수'를 세는 쿼리를 넣어서 조건으로 조회할 수 있다.

SELECT customer_id
FROM   customer
GROUP  BY 1
HAVING Count(DISTINCT product_key) = (SELECT Count(DISTINCT product_key)
                                      FROM   product);

문제에서 구하라고 한 게 '모든 상품을 다 산 고객의 id'이므로, customer_id별로 그루핑해 주되 '각 id에 딸린 product_key의 숫자'가 '전체 product_key의 고유 숫자, 즉 모든 상품의 수'와 일치하도록 조건을 설정했다.

106번은 가리키는 대상과 주체가 같은 테이블에 들어가 있어서 필연적으로 서브쿼리를 쓸 수밖에 없는 문제였던 것 같다. 문제에서 구하라고 한 reports_count와 average_age를 먼저 구해준다.

SELECT reports_to,
       Count(reports_to)  AS reports_count,
       Round(Avg(age), 0) AS average_age
FROM   employees
GROUP  BY 1 

그리고 여기서의 reports_to와 메인 쿼리의 employee_id가 같은 것이 조건이므로 left join으로 두 쿼리를 연결시킨다.

SELECT employee_id,
       name,
       reports_count,
       average_age
FROM   employees e
       LEFT JOIN (SELECT reports_to,
                         Count(reports_to)  AS reports_count,
                         Round(Avg(age), 0) AS average_age
                  FROM   employees
                  GROUP  BY 1) AS a
              ON e.employee_id = a.reports_to

마지막으로 문제에서 적어도 1명 이상으로부터 보고를 받는 매니저의 데이터를 출력하라고 했으니 where절을 써서 reports_count가 1회 이상인 조건을 넣고 문제의 요구사항을 반영해 order by를 하면 끝.

SELECT employee_id,
       name,
       reports_count,
       average_age
FROM   employees e
       LEFT JOIN (SELECT reports_to,
                         Count(reports_to)  AS reports_count,
                         Round(Avg(age), 0) AS average_age
                  FROM   employees
                  GROUP  BY 1) AS a
              ON e.employee_id = a.reports_to
WHERE  reports_count >= 1
ORDER  BY 1 

항상 작은 단위 연산에서 큰 단위 연산으로.


알고리즘 코드카타 32번

길이가 같은 정수 배열 a,b의 내적을 구하는 문제. a와 b의 첫번째 값끼리 곱하고, 두번째 값끼리 곱하고... 해서 n번째 값까지 곱해서 전부 더하면 된다.

간단한 풀이는 이렇게 된다.

def solution(a,b):
    answer = 0
    for i in range(len(a)):
        answer += a[i]*b[i]
    return answer

어차피 a와 b의 길이는 같으므로 range의 범위는 len(a)로 하든 len(b)로 하든 관계없다. 문제의 요구사항을 있는 그대로 코드로 구현한 버전.

파이썬 과제 하면서 배웠던 zip을 쓰면 이렇게도 만들 수 있다.

def solution(a,b):
    return sum([x*y for x,y in zip(a,b)])

과제 할 때도 튜터님과 파이썬 경험 있는 팀원들이 똑같이 했던 얘기가 'zip은 정말 쓸 곳이 많다'는 것이었다. 쓸 수 있는 문제가 나올 때마다 꼭 활용해서 풀어보기.

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

0개의 댓글

관련 채용 정보