문제 링크
64.https://school.programmers.co.kr/learn/courses/30/lessons/77487
문제62.
CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블에서 대여 시작일이 2022년 9월에 속하는 대여 기록에 대해서 대여 기간이 30일 이상이면 '장기 대여' 그렇지 않으면 '단기 대여' 로 표시하는 컬럼(컬럼명: RENT_TYPE)을 추가하여 대여기록을 출력하는 SQL문을 작성해주세요. 결과는 대여 기록 ID를 기준으로 내림차순 정렬해주세요.
SELECT HISTORY_ID, CAR_ID,
DATE_FORMAT(START_DATE, '%Y-%m-%d')START_DATE,
DATE_FORMAT(END_DATE, '%Y-%m-%d')END_DATE,
IF(DATEDIFF(END_DATE , START_DATE) >= 29, '장기 대여','단기 대여')RENT_TYPE
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE START_DATE LIKE '2022-09%'
ORDER BY 1 DESC;
SELECT history_id, car_id,
substr(start_date, 1, 10) as start_date,
substr(end_date, 1, 10) as end_date,
CASE WHEN datediff(end_date, start_date)+1 < 30 THEN '단기 대여'
ELSE '장기 대여' END AS rent_type
FROM car_rental_company_rental_history
WHERE start_date LIKE '2022-09-%'
GROUP BY 1
ORDER BY 1 DESC;
SELECT HISTORY_ID, CAR_ID, date_format(START_DATE,'%Y-%m-%d') START_DATE , date_format(END_DATE,'%Y-%m-%d')END_DATE,
case when DATEDIFF(END_DATE,START_DATE) >= 29 then '장기 대여'
else '단기 대여' end as RENT_TYPE
from CAR_RENTAL_COMPANY_RENTAL_HISTORY
where date_format(START_DATE,'%Y-%m')='2022-09'
order by 1 desc
select history_id, car_id, date_format(start_date, '%Y-%m-%d'), date_format(end_date, '%Y-%m-%d'),
case when datediff(end_date, start_date) >= 29 then '장기 대여'
else '단기 대여' end 'rent_type'
from CAR_RENTAL_COMPANY_RENTAL_HISTORY
where Month(start_date) = '9'
order by history_id desc
SELECT HISTORY_ID, CAR_ID,
SUBSTR(START_DATE,1,10) AS START_DATE,
SUBSTR(END_DATE,1,10) AS END_DATE,
IF(DATEDIFF(END_DATE, START_DATE)+1>=30, '장기 대여', '단기 대여') AS RENT_TYPE
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE SUBSTR(START_DATE, 1, 7) = '2022-09'
ORDER BY HISTORY_ID DESC
best
SELECT history_id, car_id,
substr(start_date, 1, 10) as start_date,
substr(end_date, 1, 10) as end_date,
CASE WHEN datediff(end_date, start_date)+1 < 30 THEN '단기 대여'
ELSE '장기 대여' END AS rent_type
FROM car_rental_company_rental_history
WHERE start_date LIKE '2022-09-%'
GROUP BY 1
ORDER BY 1 DESC;
모두 비슷한 방법으로 풀이!
이문제의 핵심은 datediff사용이고, datediff가 '0'인 경우가 발생하기 때문에 이런 경우, +1을 해줘야한다.
그렇지 않은 경우 30일이 아니라 29일로 계산!
문제64.
이 서비스에서는 공간을 둘 이상 등록한 사람을 "헤비 유저"라고 부릅니다. 헤비 유저가 등록한 공간의 정보를 아이디 순으로 조회하는 SQL문을 작성해주세요.
SELECT *
FROM PLACES
WHERE HOST_ID IN(SELECT HOST_ID
FROM PLACES
GROUP BY HOST_ID
HAVING COUNT(ID)>=2
)
ORDER BY 1;
SELECT *
FROM places
WHERE host_id IN (SELECT host_id
FROM places
GROUP BY host_id
HAVING count(name)>=2)
ORDER BY id;
SELECT *
from PLACES
where HOST_ID in (select HOST_ID
from PLACES
group by HOST_ID
having count(HOST_ID)>=2)
order by ID
select *
from places
where host_id in
(
select host_id
from places
group by host_id
having count(id) >= 2
)
order by id
SELECT *
FROM PLACES
WHERE HOST_ID IN
( SELECT HOST_ID
FROM PLACES
GROUP BY HOST_ID
HAVING COUNT(id) >= 2
) #count(*)는 null이 group by에 잡혀서 안될듯
ORDER BY ID
best
SELECT *
FROM PLACES
WHERE HOST_ID IN(SELECT HOST_ID
FROM PLACES
GROUP BY HOST_ID
HAVING COUNT(ID)>=2
)
ORDER BY 1;
일단 중첩서브 쿼리를 사용하는 문제로, 모든 컬럼을 조회하되 조건절에 host_id가 in안에 들어가는 조건에 부합하는 것만 가져와야한다.
문제에서 주어진 조건을 in안에 넣어 풀이했다.
이때 처음에 count(host_id)를 했지만, 이미 호스트 아이디로 그룹화 한상태이므로 id나 이름의 수를 세는 것이 더 맞다는 생각이 들었다.
사용문법
DATEDIFF():
중첩 서브쿼리
IN()
COUNT(집계하고자하는 특성의 칼럼) # null인 경우의 이상치는 제외해주어야 하니까 해당 특성의 칼럼으로 명시해주는게 더 정확할 것