SELECT -- 자동차 ID, 자동차 종류, 대여 금액(컬럼명: FEE) 출력
C.CAR_ID
, C.CAR_TYPE
-- FEE: (대여 날짜 * 하루 대여비) * 할인적용률 -> 소수점 반올림(.00 제거)
, CASE WHEN DATEDIFF(H.END_DATE,H.START_DATE)+1 >= 30
THEN ROUND(C.DAILY_FEE * (DATEDIFF(H.END_DATE,H.START_DATE)+1) * 0.93)
WHEN DATEDIFF(H.END_DATE,H.START_DATE)+1 >= 7
THEN ROUND(C.DAILY_FEE * (DATEDIFF(H.END_DATE,H.START_DATE)+1) * 0.95)
ELSE C.DAILY_FEE * (DATEDIFF(H.END_DATE,H.START_DATE)+1)
END FEE
FROM -- 3개 태이블 조인
CAR_RENTAL_COMPANY_CAR C
LEFT JOIN
CAR_RENTAL_COMPANY_RENTAL_HISTORY H ON C.CAR_ID = H.CAR_ID
JOIN
CAR_RENTAL_COMPANY_DISCOUNT_PLAN P ON C.CAR_TYPE = P.CAR_TYPE
WHERE
P.CAR_TYPE IN ('세단','SUV') AND -- '세단' or 'SUV'
H.END_DATE < '2022-11-01' AND H.START_DATE < '2022-11-01' AND -- 2022-11-01 ~ 2022-11-30 대여 가능
(C.DAILY_FEE * 30) - (C.DAILY_FEE * 30 * 0.1) >= 500000 AND -- 30일간의 대여 금액 >= 50만원
(C.DAILY_FEE * 30) - (C.DAILY_FEE * 30 * 0.1) < 2000000 -- 30일간의 대여 금액 < 200만원
ORDER BY -- 대여 금액 DESC, 차 종류ASC, 자동차 ID DESC
3 DESC, 2, 1 DESC
JOIN 시 디폴트는 INNER JOIN이다. 위 사례에서 첫 번째 조인은 CAR_RENTAL_COMPANY_CAR 'LEFT JOIN'CAR_RENTAL_COMPANY_RENTAL_HISTORY 'ON' 을 했어야 했다.
그래야 한번도 렌탈되지 않았지만 렌탈 가능한 차량이 조회되기 때문이다.
JOIN - AND 로 WHERE절 필터링을 상당수 대체할 수 있다.
select
a.car_id,
a.car_type,
round(a.daily_fee*30*((100-b.discount_rate)/100)) as fee
# c.*
from CAR_RENTAL_COMPANY_CAR as a
inner join CAR_RENTAL_COMPANY_DISCOUNT_PLAN as b
on a.car_type = b.car_type and a.car_type IN ('세단', 'SUV') and b.duration_type = '30일 이상'
left join CAR_RENTAL_COMPANY_RENTAL_HISTORY as c
on a.car_id = c.car_id and c.end_date > '2022-11-01'# and c.car_id is null
where c.history_id is null -- 2022년 11월 1일 이후에 대여 기록이 없는 자동차
having fee >= 500000 and fee < 2000000
order by 3 desc, 2, 1 desc
각 조인별로 해당되는 테이블에서 수행할 수 있는 필터링을 AND로 수행하였기에 정확도와 가독성이 높아진다.
LEFT JOIN 으로 발생한 NULL값을 필터링에 사용하셨다.
zip() 함수를 사용하는 문제
def solution(a, b):
answer = 0 # answer 변수 초기화, 반복해서 더해줘야 하니까.
for x, y in zip(a, b): # for i in x: x에서 i를 하나씩 뽑아서 반복
answer = answer + x*y # 반복해서 더해줌
return answer # zip(a,b) 가 key point
아직까지도 for반복문을 바로 사용하지 못한다..
이래서 나중에 크롤링은 어떻게 할 것이며 머신러닝은 어떻게 돌릴거냐?
오늘 순공시간 3시간.. 반성하고 내일은 순공시간을 6시간 이상으로 가져가자.
그래도 zip()함수 하나를 알고 넘어가는 오늘이다.
zip(iterator1, iterator2, iterator3 ...): 하위 쿼리를 정의하고 참조하는 방법
WITH cte_name AS (
SELECT column1, column2, ...
FROM table_name
WHERE condition
)
SELECT column1, column2, ...
FROM cte_name;
: 자기 자신을 반복적으로 호출하여 계층적/반복적 데이터를 처리한다. 엥커, 재귀로 구성됨.
UNION ALL은 모든 결과 행을 포함하는 반면 UNION은 중복된 행을 제거한다. RECURSIVE CTE에서는 보통 의도적으로 중복된 행을 포함하기에 UNION ALL을 사용한다. WITH RECURSIVE cte_name AS (
-- 앵커 멤버
SELECT initial_query
UNION ALL
-- 재귀 멤버
SELECT recursive_query
FROM cte_name
WHERE termination_condition
)
SELECT * FROM cte_name;
0 ~ 10 숫자를 생성하는 재귀CTE 예제
WITH RECURSIVE Numbers AS (
-- 앵커 멤버: 0을 반환
SELECT 0 AS number
UNION ALL
-- 재귀 멤버: number에 1을 더해가면서 10 이하일 때까지 반복
SELECT number + 1
FROM Numbers
WHERE number < 10
)
SELECT number FROM Numbers;
zip(iterator1, iterator2, iterator3 ...)a = ("John", "Charles", "Mike")
b = ("Jenny", "Christy", "Monica", "Vicky")
x = zip(a, b)
#use the tuple() function to display a readable version of the result:
print(tuple(x))
# 결과: (('John', 'Jenny'), ('Charles', 'Christy'), ('Mike', 'Monica'))