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
JOIN rest_review r
ON i.rest_id = r.rest_id
WHERE i.address LIKE '서울%'
GROUP BY i.rest_id
ORDER BY score DESC, i.favorites DESC
GROUP BY 절은 집계 함수(예: AVG(), SUM(), COUNT() 등)와 함께 사용될 때 필요한 SQL 절입니다. 이 절은 데이터를 특정 기준으로 그룹화하여 각 그룹에 대해 집계 함수를 적용할 수 있도록 합니다. 예를 들어, AVG() 함수는 각 그룹에 대해 평균을 계산하는데, 이 그룹이 지정되지 않으면 SQL 엔진은 어떤 기준으로 평균을 계산해야 할지 알 수 없습니다.
즉, AVG(RR.REVIEW_SCORE)를 사용하여 식당별 리뷰 평균을 계산하려면, 이 집계가 식당별로 계산되도록 해야 합니다. GROUP BY 절이 없으면 SQL은 전체 테이블을 하나의 그룹으로 보고 전체 평균을 계산해 버리기 때문에, 식당별로 계산이 이루어지지 않습니다.
따라서, 식당마다 별도의 그룹을 만들어야 리뷰 점수의 평균을 식당별로 구할 수 있고, 이를 위해 GROUP BY 절이 필요합니다.
REST_ID는 식당별로 고유한 값이므로, 식당별로 그룹화할 때 적합한 기준입니다. 즉, 각 REST_ID는 하나의 식당을 의미하므로 이를 기준으로 그룹을 나누면 각 식당의 리뷰 점수 평균을 별도로 구할 수 있습니다.
만약 그 외의 다른 컬럼(REST_NAME, FOOD_TYPE 등)을 GROUP BY에 포함시키지 않고 REST_ID만 그룹화 기준으로 삼는 경우, 다른 컬럼들은 암묵적으로 해당 그룹의 첫 번째 행에서 선택됩니다. 하지만 이렇게 하려면 각 REST_ID에 대해 해당하는 REST_NAME이나 FOOD_TYPE 값이 고유해야 합니다. 즉, REST_ID가 동일하면 해당 레코드들의 나머지 값들도 동일하다는 전제가 있어야 합니다. 식당 정보에서 이 전제가 성립할 가능성이 높습니다.
그러나, SQL 표준에 따르면 GROUP BY 절에 포함되지 않은 컬럼을 SELECT에 사용할 때, MySQL은 비결정적(non-deterministic) 결과를 반환할 수 있습니다. 이를 피하기 위해 일반적으로 GROUP BY에 사용하는 모든 컬럼을 명시하는 것이 더 명확하고 안전한 방법입니다.
결론:
GROUP BY 절은 리뷰 평균을 식당별로 계산하기 위해 필요합니다.
REST_ID만으로 그룹화하는 경우는 각 식당에 대한 고유한 정보가 동일하다는 전제하에 가능합니다.
HAVING 절은 집계 함수(예: AVG(), COUNT(), SUM())를 사용한 결과에 조건을 적용할 때 사용됩니다. ADDRESS 컬럼 관련해서는 집계 함수와 관계없는 일반 조건이므로, WHERE 절을 사용하는 것이 더 적절합니다.
: 지정된 열의 값들의 평균을 계산하는 함수
SELECT AVG(열이름)
FROM 테이블이름
[WHERE 조건];
숫자 데이터 처리: AVG() 함수는 숫자형 데이터에서만 사용할 수 있습니다. INT, FLOAT, DECIMAL과 같은 데이터 타입에서 동작하며, 문자열이나 날짜 타입에는 사용할 수 없습니다.
NULL 값 무시: AVG() 함수는 계산할 때 NULL 값을 무시합니다. 즉, 해당 열에 NULL이 있더라도 평균 계산에 영향을 주지 않습니다. 예를 들어, 값이 [100, NULL, 200]인 경우, AVG()는 150을 반환합니다 ((100 + 200) / 2 = 150).
그룹화와 함께 사용 가능: AVG() 함수는 GROUP BY와 함께 자주 사용되어, 특정 그룹별로 평균 값을 계산할 수 있습니다. 예를 들어, 부서별로 평균 급여를 구할 때 유용합니다.
소수점 제어: AVG() 함수는 소수점을 포함한 결과를 반환할 수 있으며, ROUND() 함수를 사용하여 소수점 자릿수를 제어할 수 있습니다.
다음은 salary 테이블에서 전체 직원의 평균 급여를 구하는 쿼리입니다.
SELECT AVG(salary) AS avg_salary
FROM salary;
부서별로 평균 급여를 구하려면 GROUP BY를 사용합니다:
SELECT department_id, AVG(salary) AS avg_salary
FROM salary
GROUP BY department_id;
ROUND()와 함께 사용
: 결과를 소수점 두 번째 자리까지 반올림하고 싶다면 ROUND() 함수를 사용할 수 있습니다:
SELECT ROUND(AVG(salary), 2) AS avg_salary
FROM salary;
이 쿼리는 평균 급여를 소수점 두 자리로 반올림합니다.
ROUND() 함수는 숫자를 반올림하는 함수로, 소수점 아래에서 원하는 자릿수까지 숫자를 반올림합니다.
ROUND(숫자, 자릿수)
SELECT ROUND(123.4567, 2); -- 결과: 123.46
SELECT ROUND(123.4567, 0); -- 결과: 123
SELECT ROUND(123.4567, -1); -- 결과: 120 (정수 부분에서 반올림)
ROUND(123.4567, 2)는 소수점 두 번째 자리까지 반올림하여 123.46을 반환합니다.
자릿수를 0으로 설정하면 정수로 반올림합니다.
음수를 넣으면 정수 부분에서 반올림을 수행합니다.
FORMAT() 함수는 숫자를 포맷팅하여 문자열로 반환하는 함수입니다. 숫자를 특정 형식(주로 소수점 자릿수와 천 단위 구분 포함)으로 변환하여, 보다 읽기 쉽게 만듭니다. 결과는 문자열로 반환되기 때문에, 숫자와 관련된 연산에는 사용할 수 없습니다.
FORMAT(숫자, 자릿수)
SELECT FORMAT(1234567.891, 2); -- 결과: '1,234,567.89'
SELECT FORMAT(1234567.8, 0); -- 결과: '1,234,568'
SELECT FORMAT(1234567, 2); -- 결과: '1,234,567.00'
FORMAT(1234567.891, 2)는 1,234,567.89라는 문자열을 반환하며, 천 단위 구분자인 쉼표(,)를 포함합니다.
자릿수를 0으로 설정하면 소수점 없이 천 단위 구분자만 추가된 형식으로 반환됩니다.