ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • SQL - 특정 기간 지정 / distinct,group ?
    카테고리 없음 2024. 4. 29. 17:45

    코딩테스트 연습 - 특정 기간동안 대여 가능한 자동차들의 대여비용 구하기 | 프로그래머스 스쿨 (programmers.co.kr)

     

    프로그래머스

    코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

    programmers.co.kr

    with h as 
          (SELECT car_id 
           FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY 
           WHERE  end_date >= '2022-11-01' and start_date <= '2022-11-30' )
          ,dp as 
          (
              select *
           from CAR_RENTAL_COMPANY_DISCOUNT_PLAN dp
           where duration_type like '30%'
           ),
          c as 
          (
              select *
           from CAR_RENTAL_COMPANY_CAR c
           where c.car_type in ('세단', 'SUV')
           )     
    SELECT 
    c.car_id,c.car_type
    , floor(c.daily_fee*(100-dp.discount_rate)/100)*30 as fee
    from  
    c
    left join dp on c.car_type = dp.car_type
    where  
    floor(c.daily_fee*(100-dp.discount_rate)/100)*30 between 500000 and 2000000
    and car_id not in (select car_id from h)
    order by 
    fee desc, c.car_type asc, c.car_id desc

    1.

    날짜 범위 지정이 좀 많이 어려웠다.

     

    기존 알고 있는 개념을 이용하여 풀려고 하였던 방식인 p,np를 이용하기도 하고, 데이터 추출에 의미를 둬야 하는 만큼 단계적으로 제거하려고도 해보았었다.

    하지만 문제를 풀면서 '난 분명 제외한 데이터인데 왜 포함되어있지?'라는 생각이 드는 경우가 존재했다. 

    SELECT * FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY CCR
    WHERE end_date < '2022-11-01' OR start_date > '2022-11-30';

    이렇게 기간을 제한하여 조회하였으나 

    ...
    where 
         (CAR_ID IN 
          (SELECT CAR_ID 
    ...
    where
    	(history_id in
        	(select history_id
    ...

    와 같이 다른 컬럼명을 이용하여도 

    위의 벗어난 값을 가진 두 car_id가

    이렇게 여러번의 대여 기록을 가지고 있어 계속 포함되어 결과값이 어긋나는 모습을 보여주고 있었다.

    이러한 일이 발생한 이유는 

    i) or로 데이터 연결

    ii) 이로 인해 start 에서는 제외되었지만, end에서 제외되지 않은 데이터가 포함된다

    로 줄일 수 있다. 

     

    그렇다면 이 경우의 np인

    with h as 
          (SELECT car_id 
           FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY 
           WHERE  end_date >= '2022-11-01' and start_date <= '2022-11-30' )
    ...
    with
    ...
    and car_id not in (select car_id from h)

    상단 정답 방식으로 적용하면 위의 문제가 해결된다. 

    왜 차이가 날까?

    => 일부가 나뉘던 기존과는 달리 CAR_ID 단위로 제외되었기 때문.

     

     

    2.

    제목에 있는 group 과 distinct 가 없다.

    이렇게 만들기 위해 많은것을 대조해보았고 그 원인인 car_id에서 중복이 발생하여 그 원인이 무엇인가를 찾아보았는데

    with h as 
        (
    select distinct car_id
          from 
           CAR_RENTAL_COMPANY_RENTAL_HISTORY h
          where 
         car_id not IN 
          (SELECT car_id 
           FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY 
           WHERE  end_date >= '2022-11-01' and start_date <= '2022-11-30' 
          )
    ...      
    from  
    h
    left join  c on h.car_id = c.car_id 
    left join dp on c.car_type = dp.car_type
    ...

    common table expression 에서 다시한번 history 원 테이블을 호출하면서 Id의 중복이 발생하였다.

    그렇다면 왜 

    SELECT car_id 
    FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY 
    WHERE  end_date >= '2022-11-01' and start_date <= '2022-11-30'

    여기선 중복된 id값이 나오지 않을까?

    => Table 자체에서 우연찮게 unique 한 값을 가지고 있었기에 distinct를 사용하지 않았을 뿐,

         원래라면 사용하는 것이 옮다. 

     

Designed by Tistory.