프로그래머스에서 제공하는 SQL문제 매일 풀기 챌린지
문제 설명
다음은 어느 자동차 대여 회사에서 대여 중인 자동차들의 정보를 담은 CAR_RENTAL_COMPANY_CAR 테이블과 자동차 대여 기록 정보를 담은 CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블입니다. CAR_RENTAL_COMPANY_CAR 테이블은 아래와 같은 구조로 되어있으며, CAR_ID, CAR_TYPE, DAILY_FEE, OPTIONS 는 각각 자동차 ID, 자동차 종류, 일일 대여 요금(원), 자동차 옵션 리스트를 나타냅니다.
Column name | Type | Nullable |
CAR_ID | INTEGER | FALSE |
CAR_TYPE | VARCHAR(255) | FALSE |
DAILY_FEE | INTEGER | FALSE |
OPTIONS | VARCHAR(255) | FALSE |
자동차 종류는 '세단', 'SUV', '승합차', '트럭', '리무진' 이 있습니다. 자동차 옵션 리스트는 콤마(',')로 구분된 키워드 리스트(예: '열선시트', '스마트키', '주차감지센서')로 되어있으며, 키워드 종류는 '주차감지센서', '스마트키', '네비게이션', '통풍시트', '열선시트', '후방카메라', '가죽시트' 가 있습니다.
CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블은 아래와 같은 구조로 되어있으며, HISTORY_ID, CAR_ID, START_DATE, END_DATE 는 각각 자동차 대여 기록 ID, 자동차 ID, 대여 시작일, 대여 종료일을 나타냅니다.
Column name | Type | Nullable |
HISTORY_ID | INTEGER | FALSE |
CAR_ID | INTEGER | FALSE |
START_DATE | DATE | FALSE |
END_DATE | DATE | FALSE |
문제
CAR_RENTAL_COMPANY_CAR 테이블과 CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블에서 자동차 종류가 '세단'인 자동차들 중 10월에 대여를 시작한 기록이 있는 자동차 ID 리스트를 출력하는 SQL문을 작성해주세요. 자동차 ID 리스트는 중복이 없어야 하며, 자동차 ID를 기준으로 내림차순 정렬해주세요.
예시
예를 들어 CAR_RENTAL_COMPANY_CAR 테이블이 다음과 같고
CAR_ID | CAR_TYPE | DAILY_FEE | OPTIONS |
1 | 세단 | 16000 | 가죽시트,열선시트,후방카메라 |
2 | SUV | 14000 | 스마트키,네비게이션,열선시트 |
3 | 세단 | 22000 | 주차감지센서,후방카메라,가죽시트 |
4 | 세단 | 12000 | 주차감지센서 |
CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블이 다음과 같다면
HISTORY_ID | CAR_ID | START_DATE | END_DATE |
1 | 4 | 2022-09-27 | 2022-09-27 |
2 | 3 | 2022-10-03 | 2022-10-04 |
3 | 2 | 2022-10-05 | 2022-10-05 |
4 | 1 | 2022-10-11 | 2022-10-14 |
5 | 3 | 2022-10-13 | 2022-10-15 |
10월에 대여를 시작한 기록이 있는 '세단' 종류의 자동차는 자동차 ID가 1, 3 인 자동차이고, 자동차 ID를 기준으로 내림차순 정렬하면 다음과 같이 나와야 합니다
CAR_ID |
3 |
1 |
정답 2가지 버전
10월에 대여를 시작한 기록이 있는 자동차에 대한 데이터만 출력하기 위해서
대여시작일(start_date) 데이터에서 2022년 10월의 데이터만 출력해야한다.
이를 출력하는 방법으로 2가지가 있다.
1. TO_CHAR 혹은 MySQL의 경우 DATE_FROMAT 함수를 사용하여 문제 해결
2. TO_DATE 혹은 MySQL의 경우 STR_TO_DATE 함수 + BEWEEN .. AND를 사용하여 문제 해결
따라서 오라클은 1번 방법으로 해결해보고
MySQL은 2번 방법으로 해결하여 두 가지 방법 모두 수행해보자
♥ 오라클 정답 : TO_CHAR () 함수와 LIKE 연산자 사용
select distinct h.car_id
from car_rental_company_rental_history h, car_rental_company_car c
where h.car_id = c.car_id
and to_char(h.start_date, 'RRRRMM') like '202210'
and c.car_type = '세단'
order by h.car_id desc;
♥ MySQL 정답 : STR_TO_DATE() 함수와 BETWEEN .. AND 사용
select distinct h.car_id
from car_rental_company_rental_history h, car_rental_company_car c
where h.car_id = c.car_id
and h.start_date between str_to_date('20221001', '%Y%m%d') and str_to_date('20221031', '%Y%m%d')
and c.car_type = '세단'
order by h.car_id desc;
오라클로 수행한 TO_CHAR() 방법 해설
대여시작일(start_date) 데이터에서 2022년 10월의 데이터를
to_char(mysql에서는 date_format)함수로
data type을 문자형으로 변환하여 like 를 사용해 2022년 10월 데이터만 출력할 수 있다.
● to_char 함수와 date_format 함수 문법 설명
Oracle의 경우
▶ TO_CHAR([컬럼명], '변경할 데이터 형태')
위의 함수를 사용해서 날짜형 데이터 형식을 → 문자형 데이터 형식으로 변환한다.
* 표시한 형태 해석(오라클의 경우 대소문자 구분 없음)
- RRRR/YYYY : Year 연도 4자리로 표기(ex. 2023, 2024)
- MM : Month 월 2자리로 표기 (ex. 05, 07)
- DD : Day 일 2자리로 표기 (ex. 01, 31)
MySQL의 경우
▶ DATE_FORMATE([컬럼명], '변경할 데이터 형태' ) 함수
* 표시한 형태 해석(대소문자 구분 있음)
- %Y : Year 연도를 4자리로 표기 (ex. 2023, 2024)
- %m : Month 월을 2자리로 표기(ex. 05, 12)
- %d : Day 일을 두 자리로 표기(ex. 04, 28)
* 참고
- %c :Month 월을 한 자리로 표기(ex. 5, 12)
- %e :Day 일을 한자리로 표기(ex. 4, 28)
# 1. SELECT절
자동차 ID(car_id)가 출력될 때 중복 없이 출력되어야 하므로
distince를 사용하여 중복을 제거해준다.
# 2. FROM절
데이터를 가져올 테이블들을 작성해주는데,
테이블의 별칭도 함께 나열해준다.
# 3. WHERE절
두 테이블의 데이터 중 car_id가 일치하기 때문에
각 테이블의 car_id 컬럼을 연결조건으로 사용하여 equi join 해준다.
# 3-1. WHERE절의 일반조건
and로 연결조건과 연결해 준 후 car_type이 '세단'인 데이터를 추출해준다.
또 다른 일반 조건이 존재하여 and로 조건을 연결해준 뒤
TO_CHAR함수를 사용하여 2022년 10월을 데이터만 추출할 수 있도록 해준다.
이때 함께 사용할 수 있는 것이 LIKE 연산자이다.
▶ LIKE 연산자
특정 패턴을 가진 문자열을 검색할 때 사용한다.
여기서 와일드카드 % 는
해당 자리에 0개 이상의 아무런 값이나 와도 상관 없다는 의미로
개수, 숫자, 문자 상관 없이 아무런 값이 들어가도 된다는 의미이다.
MySQL로 수행한 STR_TO_DATE와 BETWEEN .. AND방법 해설
# 1. SELECT절
자동차 ID(car_id)가 출력될 때 중복 없이 출력되어야 하므로
distince를 사용하여 중복을 제거해준다.
# 2. FROM절
데이터를 가져올 테이블들을 작성해주는데,
테이블의 별칭도 함께 나열해준다.
# 3. WHERE절
두 테이블의 데이터 중 car_id가 일치하기 때문에
각 테이블의 car_id 컬럼을 연결조건으로 사용하여 equi join 해준다.
# 3-1. WHERE절의 일반조건
and로 연결조건과 연결해 준 후 car_type이 '세단'인 데이터를 추출해준다.
또 다른 일반 조건이 존재하여 and로 조건을 연결해준다.
그 조건은 2022년 10월에 해당하는 데이터를 걸러주는 것인데,
여기서는 20221001 ~ 20221031 로 조건을 주어 문제를 해결할 수 있다.
20221001 ~ 20221031 는 그냥 숫자의 형태이기 때문에 DATE 형식으로
데이터 포맷을 변경해주기 위해서 STR_TO_DATE 함수를 사용해준다.
(oracle의 경우 TO_DATE 함수를 사용해주면 된다.)
▶ STR_TO_DATE( [컬럼명or 값], [형태] )
문자나 숫자 형식의 데이터를 날짜 형식으로 변환해주는 함수이다.
* 표시한 형태 해석(대소문자 구분 있음)
- %Y : Year 연도를 4자리로 표기 (ex. 2023, 2024)
- %m : Month 월을 2자리로 표기(ex. 05, 12)
- %d : Day 일을 두 자리로 표기(ex. 04, 28)
* 참고
- %c :Month 월을 한 자리로 표기(ex. 5, 12)
- %e :Day 일을 한자리로 표기(ex. 4, 28)
결과 출력
출처 : 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges
'SQL 문제 풀기 > 1. 프로그래머스 SQL : 2023.12.17~2024.2.29' 카테고리의 다른 글
<프로그래머스 56> 없어진 기록 찾기(Lv.3) (2) | 2024.02.10 |
---|---|
<프로그래머스 55> 즐겨찾기가 가장 많은 식당 정보 출력하기(Lv.3) (2) | 2024.02.09 |
<프로그래머스 53> 조건에 맞는 사용자와 총 거래금액 조회하기(Lv.3) (4) | 2024.02.07 |
<프로그래머스 52> 오랜 기간 보호한 동물(2)(Lv.3) (2) | 2024.02.06 |
<프로그래머스 51> 조건별로 분류하여 주문상태 출력하기(Lv.3) (2) | 2024.02.05 |