240512_TIL

J Lee·2024년 5월 12일
0

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

SQL 코드카타 113번
manager가 회사에 없는 직원의 id를 출력하는 문제.
manager가 퇴사를 해도 id가 지워지지는 않는다는 게 포인트.
(아예 null인 경우는 애초에 매니저가 없다는 뜻)

SELECT e1.employee_id
FROM   employees e1
       LEFT JOIN employees e2
              ON e1.manager_id = e2.employee_id
WHERE  e1.manager_id IS NOT NULL
       AND e2.employee_id IS NULL
       AND e1.salary < 30000
ORDER  BY 1

만약 매니저가 퇴사한 상황이라면

  1. e1 테이블에는 (id가 지워지지는 않는다고 했으므로) id가 남아있을 것 → e1.manager_id는 null이 아니어야 하고
  2. e2 테이블의 employee_id에는 (지금 있는 사람이 아니므로) id가 없어야 한다

같은 테이블 2개를 left join해서 manager_id가 employee_id와 같은 경우만 뽑고 salary 조건과 order by를 적용해 주면 끝.

SQL 코드카타 114번
자리 바꾸기 문제.
id 기준으로 둘씩 짝지어서 자리를 바꾼 결과를 출력하면 되는데, 전체 학생 수가 홀수일 경우 제일 마지막 학생은 자리를 안 바꿔도 된다.

이 문제도 어제 풀었던 salary 구간별 count 문제와 비슷한 부분이 있는데, 쿼리 한방으로 해결부터 하려고 덤비는 것보다 우선 새롭게 학생들을 정렬할 기준부터 먼저 잡아놓고 문제에서 요구하는 데이터를 마지막에 구하는 게 효율적이라는 점에서 그렇다.
항상 작은 단위 연산에서 큰 단위 연산으로.

select case when id = (select max(id) from Seat) and mod(id,2) = 1 then id
             when mod(id,2) = 1 then id+1
             when mod(id,2) = 0 then id-1
             end as id,
       student
from Seat
order by 1

case when 제일 앞부분에 특이 케이스를 처리해 준다. (id가 최대값이고 홀수일 경우는 자리를 안 바꿀 거니까 id 유지)

홀수, 짝수를 판단할 때 mod(컬럼,2)를 썼는데 파이썬처럼 id % 2로 써도 결과는 같다.

맨 처음 제출한 정답 쿼리는 id를 새롭게 정렬하는 기준을 불필요하게 복잡하게 잡았고 안 써도 되는 서브쿼리를 썼던 점에서 다소 비효율적인 쿼리였다. 정답이 나오긴 나오지만.

select a.id, s.student
from
(select id,
        case when id <> (select max(id) from Seat) and mod(id,2) = 1 then id+1
             when id <> (select max(id) from Seat) and mod(id,2) = 0 then id-1
             when id = (select max(id) from Seat) and mod(id,2) = 1 then id
             when id = (select max(id) from Seat) and mod(id,2) = 0 then id-1
             end as new_id
from Seat) a
left join Seat s on a.new_id = s.id
order by 1

알고리즘 코드카타 38번

이 문제에는 표준 입력으로 두 개의 정수 n과 m이 주어집니다.
별(*) 문자를 이용해 가로의 길이가 n, 세로의 길이가 m인 직사각형 형태를 출력해보세요.

예를 들어 5 3이 주어지면
*****
*****
*****

이렇게 나와야 한다.

a, b = map(int, input().strip().split(' '))
print(a + b)

공백을 두고 주어진 두 숫자가 함수를 통해 정수 a와 b로 각각 할당된다.

a, b = map(int, input().strip().split(' '))
answer = ('*'*a+'\n')*b
print(answer)

*을 a만큼 찍어주고 (가로 길이)
'\n'을 넣어서 줄바꿈을 한 뒤에
b번만큼 반복해주면 (세로 길이) 원하는 직사각형이 출력된다.

이중 for문을 써서 푸는 방법도 있긴 한 것 같은데, 아직은 이중 for문이 익숙하지 않기도 하고 이 방법이 더 직관적으로 알아보기 편해서 이렇게 하기로.

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

0개의 댓글