본문 바로가기

코딩테스트/SQL - 프로그래머스

SQL 고득점 kit(SELECT) - 서울에 위치한 식당 목록 출력하기

 

 

조건을 잘 만족시켜야 하는 문제였다. 같은 결과가 출력되더라도, 답이 아닐 수 있다.

 

-- 처음 풀이. 틀린 풀이.
SELECT I.REST_ID
     , I.REST_NAME
     , I.FOOD_TYPE
     , I.FAVORITES
     , I.ADDRESS
     , ROUND(AVG(R.REVIEW_SCORE), 2) AS SCORE
    FROM REST_INFO I
    LEFT JOIN REST_REVIEW R
        ON I.REST_ID = R.REST_ID
    WHERE I.ADDRESS LIKE '서울%'
    GROUP BY R.REST_ID
    ORDER BY SCORE DESC, I.FAVORITES DESC;

 

아무리 봐도 틀린 곳이 없다고 생각했지만 역시나 그것은 내 생각일 뿐이었다. 조건을 잘 만족시키지 못했었다.

 

-- 고친 정답 풀이
SELECT I.REST_ID
     , I.REST_NAME
     , I.FOOD_TYPE
     , I.FAVORITES
     , I.ADDRESS
     , ROUND(AVG(R.REVIEW_SCORE), 2) SCORE
    FROM REST_REVIEW R
    JOIN REST_INFO I
        ON R.REST_ID = I.REST_ID
    WHERE I.ADDRESS LIKE "서울%"
    GROUP BY R.REST_ID
    ORDER BY SCORE DESC, I.FAVORITES DESC;

 

위의 두 쿼리의 출력값은 같았지만, 왜 내껀 틀리고 정답 쿼리는 정답이었는가? 를 살펴보면...

 1. GROUP BY
내가 짠 쿼리는 I.REST_NAME으로 그룹화를 하는데, 이는 같은 식당 이름을 가진 다른 식당들이 있을 경우 이들을 동일한 그룹으로 취급하게 되는 반면 정답쿼리는 R.REST_ID, 즉 각 식당의 고유 ID로 그룹화를 하고 있으므로. 더 정확함.
 2. JOIN
내 쿼리에서는 LEFT JOIN을 사용했는데, 이러면 리뷰가 없는 식당 정보도 결과에 포함되고, 이 경우 리뷰가 없는 식당의 평균 점수는 NULL이 된다. 반면 정답쿼리에서는 INNER JOIN 사용했으므로 리뷰가 없는 식당은 결과에서 제외된다.
 3. WHERE 절
내 쿼리에서는 주소에 '서울'이 포함된 모든 식당을 대상으로 한다. 이는 '서울'이 주소 어디에나 포함될 수 있으므로, 혹시나 시 명이 아닌 군이나 구에 서울이 들어가는 식당이 있다면 그 식당도 포함된다. 그러나 정답쿼리에선 주소가 '서울'으로 시작하는 식당만 대상으로 하기에 더 정확하다. 물론 시 명 외 다른 주소에 서울이 들어가는 식당이 있을 것 같진 않지만.

아마 위의 이유로 내 쿼리는 정답이 아니게 처리된 것 같다.

쿼리 자체를 복잡하게 짜야 하는 문제는 아니었지만, 조건을 꼼꼼하게 따져야 하는 문제였다.