WITH
DF1 AS (SELECT REST_ID, ROUND(AVG(REVIEW_SCORE),2) AS SCORE
FROM REST_REVIEW
GROUP BY REST_ID),
DF2 AS (SELECT * FROM REST_INFO
WHERE ADDRESS LIKE '서울%')
SELECT DF2.REST_ID,
DF2.REST_NAME,
DF2.FOOD_TYPE,
DF2.FAVORITES,
DF2.ADDRESS,
DF1.SCORE
FROM DF2
INNER JOIN DF1 ON DF2.REST_ID = DF1.REST_ID
ORDER BY SCORE DESC, FAVORITES DESC
오늘의 SQL의 개념은 '서브쿼리' 이다.
일단 서브쿼리란, 쿼리안에 있는 쿼리이다.
또한 이는 두가지의 사용할 때를 나눌 수 있는데
특정 테이블에서 일부 데이터를 먼저 선택하고, 그 결과를 이용해서 다른 테이블에서 검색하는데 사용.
(예: "주문 내역 테이블"에서 최근 1주일간 판맨된 상품 목록을 찾는 경우, 서브쿼리를 사용하여, 일주일 전 날짜부터 오늘까지의 주문 내역을 선택하고, 그 결과를 이용 -> "상품정보테이블" 에서 해당 상품을 찾을 수 있다.)
DML 문에서의 사용.
보통 '주문 내역 테이블' 에서 취소된 주문을 삭제하는 경우, 서브쿼리를 사용하여 취소된 주문의 목록을 먼저 선택하고, 그 결과를 이용해 삭제할 수 있다.
이때 그렇다면 DML은 저번에 보았지만 한번 더 말하면 다음과 같다.
Data Manipulation Language : 데이터 조작 언어
즉, DB에서 데이터를 조회,추가,수정,삭제 하는데 사용되는 SQL인 것이다.
우리가 흔히 아는 CRUD 작업중에서 가장 많이 사용되는 기능이라고 생각하면 된다.
그럼 다시 돌아가서 코드를 자세하게 보자.
일단 문제에서 원하는 값은 '레스토랑 정보' 와
'리뷰 정보' 를 '결합' 해서 평점과 인기도 순으로 정렬하는 것이다.
그렇다면 서브쿼리를 나누어보자
WITH
DF1 AS (SELECT REST_ID, ROUND(AVG(REVIEW_SCORE),2) AS SCORE
FROM REST_REVIEW
GROUP BY REST_ID),
다음과 같은 서브쿼리 'DF1' 은 주어진 2개의 테이블 중 'REST_REVIEW' 테이블에서 'REST_ID' 별로 리뷰 점수의 평균을 계산해서 SCORE column으로 저장한다.
DF2 AS (SELECT * FROM REST_INFO
WHERE ADDRESS LIKE '서울%')
다음과 같은 서브쿼리인 'DF2' 는 REST_INFO 테이블에서 주소가 '서울'로 시작하는 정보를 모두 가져와달라고 했기 때문에 서울로 시작하는 레스토랑 정보를 모두 선택한 것이다.
SELECT DF2.REST_ID,
DF2.REST_NAME,
DF2.FOOD_TYPE,
DF2.FAVORITES,
DF2.ADDRESS,
DF1.SCORE
FROM DF2
INNER JOIN DF1 ON DF2.REST_ID = DF1.REST_ID
ORDER BY SCORE DESC, FAVORITES DESC
마지막으로, DF1과 DF2를 REST_ID 컬럼을 기준으로 INNER JOIN하여, DF2의 레스토랑 정보와 DF1의 평점 정보를 결합한다.
그리고, 평점을 기준으로 내림차순, 평점이 같으면 인기도를 기준으로 내림차순으로 정렬하여 반환하게 된다.