CODEKATA : SQL 56-60, ALGORITHM 27

COZY·2024년 4월 24일

CODEKATA

목록 보기
4/11
post-thumbnail

SQL 56번
특정 옵션이 포함된 자동차 리스트 구하기

SELECT *
from car_rental_company_car
where options like '%네비게이션%'
order by car_id desc

컬럼에 특정 문자가 포함된 값을 보려면 like를 사용하면 된다는 사실만 인지하면 쉽게 풀리는 문제였다.
(처음에 in을 사용했었다.)

SQL 57번
조건에 부합하는 중고거래 상태 조회하기

SELECT board_id, writer_id, title, price,
       case when `status`='sale' then "판매중"
       when `status`='reserved' then "예약중"
       when `status`='done' then "거래완료"
       end "거래상태"
from used_goods_board
where created_date = '2022-10-05'
order by board_id desc

case when절과 where절에 각각 필요한 조건을 넣으면 간단하게 해결할 수 있는 문제였다.

SQL 58번
취소되지 않은 진료 예약 조회하기

SELECT a.apnt_no,
       p.pt_name,
       p.pt_no,
       a.mcdp_cd,
       d.dr_name,
       a.apnt_ymd
from ( appointment a 
       join patient p
       on a.pt_no = p.pt_no
       join doctor d
       on a.mddr_id = d.dr_id )
where a.apnt_ymd like '2022-04-13%'
      and a.apnt_cncl_yn = 'N'
      and a.mcdp_cd = 'cs'
order by a.apnt_ymd asc

생각해 볼 포인트

  • 필요한 테이블이 3개인데 어떻게 연결 할 것인가?

    join함수를 사용해서 전부 연결하면 된다.
    join은 중첩이 가능하다.
    다만, 컬럼에서 불러올 때 헷갈리기 쉬우니,
    별칭 설정을 잘 하자!

SQL 59번
자동차 대여 기록에서 대여중 / 대여 가능 여부 구분하기

SELECT car_id,
       if (sum(s)=0,'대여 가능', '대여중') as 'availabilty'
from ( select car_id,
              case when '2022-10-16'
                         between start_date
                         and end_date then 1
                   else 0
                   end as 's'
       from car_rental_company_rental_history
     )a
group by car_id
order by car_id desc

생각해 볼 포인트

  • 2022-10-16에 대여중인 자동차를 어떻게 조건 줄 것인가?

    이 부분의 정의가 헷갈려서 문제가 막혔다.
    주어진 데이터 속에는 이제까지의 모든 대여 기록이 있는데,
    이 문제에서 우리가 필요한 것은 그 속에 존재하는 과거
    "2022년 10월 16일의 대여차량에 대한 정보"다.
    실제로 조회를 해보면, 한 차량 당 여러 행(기록)을 가진다.
    게다가 조건보다 미래 날짜가 찍힌 기록도 있다.
    이렇기에 어떻게 날짜를 조건줘야 하는지 고민에 빠졌다.
    where절을 활용해 조건을 주는 것은 불가능했는데,
    대여 로그가 아예 없거나 이후 기록만 있는 경우 제외된다.
    (=대여 가능으로 표시되어야 정답임)
    계속 막혀있다가 팀원분의 도움으로 약간의 힌트를 얻었다.
    인라인 서브쿼리를 활용해 전체 데이터에서 범위를 지정한 다음, 각각 0과 1이라는 숫자 값으로 치환한다.
    범위(2022-10-16)에 해당하는 값이 있을 경우 1을 가지고,
    해당하지 않을 경우 0의 값으로 치환되는 것.
    그리고 이후 메인쿼리에서 임의의 값을 sum했을 때,
    값이 0이라면 (=2022-10-16에 해당되는 날짜 데이터가 없다면) 대여가 가능한 상태고, 값이 1이라도 있다면 (=2022-10-16이 포함된 날짜 데이터가 존재 한다면) 대여중인 상태로 표기하면 되는 것.
    이는 if문을 사용하여 표현하면 됐다.

조건 자체가 굉장히 많고, 문제의 조건에 대한 이해와 가지고 있는 데이터 값에 대한 정보가 없으면 풀 수 없었을 것.
나중에 까먹을 때 쯤 다시 풀어보면 아마도 또 헤매지 않을까 싶긴 하다...ㅎ

SQL 60번
년, 월, 성별 별 상품 구매 회원 수 구하기

SELECT date_format(s.sales_date,'%Y') Y,
       date_format(s.sales_date,'%m') M,
       u.gender,
       count(distinct(u.user_id)) users
from user_info u join online_sale s on u.user_id = s.user_id
where gender is not null
group by 1,2,3
order by 1,2,3 asc

생각해 볼 포인트

  • 년, 월을 어떻게 따로 찢어 표현할 것인가?

    date_format이나 substr()를 이용해 각각의 컬럼으로 지정한다.

  • 중복값을 어떻게 제외하고 갯수를 구할 것인가?

    distinct를 이용해 갯수를 구할 컬럼에 중복값을 제외하고 count()함수를 씌워 구한다.


ALGORITHM 27번
번호 가리기

def solution(phone_number):
    r= len(phone_number)-4
    answer = '*'*r+phone_number[-4:]
    return answer

생각해 볼 포인트

  • 각기 다른 배열을 가진 번호를 어떻게 뒤4자리만 남길 것인가

    슬래시 함수를 이용한다. [:]를 사용하되, 시작자리에 음의 수만 넣으면 역순의 숫자만큼 남기고 모두 지우는 역할을 수행한다.

  • 가릴 자리를 어떻게 지정 할 것인가

    길이로 지정한다.
    len()함수를 쓰면 변수값의 길이를 알 수 있다.
    이렇게 받은 길이에 4를 제한다. 전체 길이에서 뒷 4자리는 제외니까.

  • *로 어떻게 교체 할 것인가

    len()함수로 알아낸 범위 만큼 아스트로크를 입력하게 한다.
    다 더해서 새로운 번호로 만들어 내는 것이라고 생각했다.
    길이에 아스트로크기호를 문자로 받아 곱하고,
    그 뒤에 남겨놓은 4개의 번호를 합친다.
    파이썬에서는 간단하게 +기호를 사용하면 문자열이 합쳐진다.

profile
데이터분석 공부하는 비전공자

0개의 댓글