SQL 61번
서울에 위치한 식당 목록 출력하기
select i.rest_id,
i.rest_name,
i.food_type,
i.favorites,
i.address,
round(avg(r.review_score),2) score
from rest_info i
inner join rest_review r
on i.rest_id = r.rest_id
where i.address like '서울%'
group by i.rest_id
order by score desc, favorites desc
반올림을 하기위해 어떤 함수를 사용해야 하는지 알고 있으면 쉽게 풀 수 있었던 문제였다.
추가로, 데이터상 주소가 서울특별시와 서울시가 혼재되어 사용되었기 때문에,
조건을 줄 때 like구문에서 기입된 데이터 간 표현의 차이가 있을 수 있다는 점을 감안하여,
필요단어의 위치를 잘 파악해 작성해야 한다.
SQL 62번
자동차 대여 기록에서 장기/단기 대여 구분하기
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 RENT_TYPE
from CAR_RENTAL_COMPANY_RENTAL_HISTORY
where start_date like '2022-09%'
order by history_id desc
생각해 볼 포인트
datediff()함수를 사용했다.
날짜의일 수 차이를 계산해주는 함수로,datediff(날짜1,날짜2)의 구조로 사용하며
날짜1에서 날짜2을 뺀 일수를 결괏값으로 내놓는다.
즉, 기간에 대한 문제가 출제되고, 시작일과 끝 날짜가 주어졌다면,
datediff()를 이용해 편하게 그 기간을 구할 수 있다.
띄어쓰기 조건까지 확인 하자.오답처리 한다.날짜의 차이를 계산할 때, 숫자끼리만 단순 계산한다.9월 5일에서 9월 3일을 빼면 2일이라는 결괏값이 나오게 됨.기간을 구할 경우, 결괏값에 +1을 하거나, 조건을 줄 때 -1을 해줘야 한다.1일이지만,2일이다. 상식을 빼고 단순 계산(연산)만 하게 되는 것을 주의하자.SQL 63번
자동차 평균 대여 기간 구하기
SELECT car_id,
round(avg(diffdate),1) AVERAGE_DURATION
from ( select car_id,
((datediff(end_date,start_date))+1) as diffdate
from CAR_RENTAL_COMPANY_RENTAL_HISTORY
)a
group by car_id
having AVERAGE_DURATION >=7
order by AVERAGE_DURATION desc, car_id desc
앞선 문제에서 datediff()함수의 치명적인(?)약점을 발견하고,
보완하는 방법을 터득했기 때문에 비교적 간단하게 처리할 수 있었던 문제.
다만, 조건이 계산된 식을 하나의 기준으로 묶고 난 결괏값을 기준으로 해야하기에,
( id에 따른 평균 대여 기간을 구하고, 소숫점 2째자리에서 반올림하고, 평균대여 기간이 7이상인 id만 출력 )
서브쿼리에서 1차 계산(대여기간)을 한 후 메인쿼리에서 평균값과 반올림을 넣어 주고,
그 값을 기준으로 조건을 줄 수 있도록 having절을 사용했다.
SQL 64번
헤비 유저가 소유한 장소
SELECT p.id, p.name, p.host_id
from places p
inner join ( select *
from places
group by host_id
having count(*) >1
)a
on p.host_id = a.host_id
order by p.id
생각해 볼 포인트
공간을 host_id로 그룹화 하고, 그 갯수가 2이상 (1초과)인 경우로 정의
앞선 조건만을 걸게되면, 출력되는 정보는 한가지가 된다.
( host별로 group이 되었기 때문에 행이 합쳐짐 )
따라서 조건을 준 쿼리를 서브쿼리로 두고,
전체 테이블에서 조건을 만족한 부분만 불러는 inner join을 활용하면
필요한 정보를 모두 출력할 수 있었다.
필요한 함수나 문장은 간단한 편이었지만,
조건에 대한 출력과 표현을 어떻게 할 것인가에 대한 고민이 필요했던 문제.
앞으로 실무에서는 이러한 상황을 더 많이 맞닥뜨리지 않을까 생각한다.
SQL 65번 🔄️다시 풀어 볼 문제
우유와 요거트가 담긴 장바구니
select cart_id
from cart_products
where name in ('milk', 'yogurt')
group by cart_id
having count(distinct name) >1
order by cart_id
생각해 볼 포인트
기준을 잘 잡으면 된다.
우선, 우리가 필요한 것은 'milk'와 'yogurt'를 구매한 사람이기에,
이 두 품목이 있는 행만 남긴다. where절에 in()을 사용하면 된다.
select cart_id
from cart_products
where name in ('milk','yogurt')
일단 milk나 yogurt를 구매한 사람의 정보만 남는다.
그리고 이 정보를 하나의 id로 묶는다.
select cart_id
from cart_products
where name in ('milk','yogurt')
group by cart_id
이렇게 하면 milk든 yogurt든 하나의 사람이 구매한 것으로 표현된다.
그렇다면 milk와 yogurt를 모두 구매한 사람은 어떻게 표현할 수 있을까?
group by가 적용된 상태에서 조건을 주어야 하기 때문에 having절을 사용한다.
(having절이 싫다면 인라인 서브쿼리를 이용한다)
우선 장바구니에 들어가 있는 품목의 수가 2이상이라면,
두 상품을 모두 구매했다고 볼 수 있을 것이다. milk와 yogurt정보만 남겨놨으니까!
그러나 한가지 품목만 2개 구매 했을 수 있기 때문에,
distinct를 통해 품목의 중복값은 제외하고 그 갯수만 카운팅해주면 된다.
count()안에는 distinct를 한 컬럼을 넣을 수 있다.
엄청나게 논리적인 생각의 흐름이 필요했던 문제였다.
어떻게 풀었는지도 기억이 안난다.
많은 해설과 정답을 참고하면서, 이해하고자 노력했다.
결론적으로 구조를 이해하니 스스로 작성할 수 있었다.
그러나 나중에도 꼭 다시 풀어봐야 할 것 같다는 생각이 든다.
AGORITHM 26번
없는 숫자 더하기
def solution(numbers):
a=0
for i in range(10):
a=i+a
answer = a - sum(numbers)
return answer
숫자의 범위가 정해져 있어서 작성하기가 비교적 쉬웠다.
0부터 9까지, 총 10개의 숫자를 모두 더한 값에서,
입력받은 수의 합을 빼주면 되니까!
만약 이 수가 길어진다면,이라는 생각으로 for구문을 통해 전체 값을 구하는 식을 만들었고,
그 이후 answer에 간단한 답을 달았다.
더 쉽게 하는 방법은 그냥 45-sum(numbers)를 해주면 된다.
즉, 범위 내 없는 값의 합이라 함은,
전체 범위에서 있는 값의 합을 뺀 것과 같다는 원리를 이용했다.