집계함수
SELECT절에 사용되며, 여러 행으로부터 하나의 결가값을 반환하는 함수이다.
종류에는 COUNT, SUM, MIN, MAX, AVG가 존재합니다.
COUNT
레코드의 수를 반환해준다.
SELECT count(*) FROM customers;
count(*)를 사용하게 되면, 모든 레코드 수를 반환하게 됩니다.
customers 테이블에는 총 120개의 레코드가 존재한다는 것을 알 수 있습니다.
⚠️주의
count 함수는 값이 NULL인 값은 집계하지 않습니다.
SELECT count(first_name) FROM customers;
first_name 컬럼에 대해서 카운트 함수를 사용하면,
count(*)의 결과에서는 모든 레코드의 수가 반환되었지만, count(first_name)을 사용하게되면 NULL인 값을 제외하고 카운팅합니다.
SELECT count(*) FROM customers WHERE first_name IS NULL;
그래서, NULL인 값만 카운팅해보면,
6(120 - 114)가 반환되는 것을 확인할 수 있습니다.
SUM
숫자형 데이터 컬럼의 값의 합을 반환합니다.
id | name | no_seats |
1 | A | 72 |
2 | B | 36 |
3 | C | 36 |
위와같이 rooms 테이블이 존재할 때, no_seats 컬럼들의 합을 구하고 싶으면
SELECT sum(no_seats) FROM rooms;
sum함수에 합을 구하고자하는 컬럼명을 전달합니다.
결과, 144 (72 + 36 + 36)이 출력됩니다.
만약, 숫자형 테이터 타입이 아닌 컬럼을 대상으로 사용하면 ?
위와같이 문자열 타입인 name 컬럼을 대상으로하면 0이 반환됩니다.
MIN & MAX
컬럼의 최소값과 최대값을 반환합니다.
SELECT MIN(no_seats) FROM rooms;
위에 동일한 rooms 테이블을 대상으로 no_seats 컬럼의 최소값을 구해보면,
SELECT max(no_seats) FROM rooms;
최대값을 구해보면,
MIN과 MAX는 문자열에서도 사용이 가능합니다.
SELECT min(name) FROM rooms;
위와같이 실행하게 되면,
SELECT name FROM rooms ORDER BY name LIMIT 1;
위의 SQL과 동일한 결과값이 출력됩니다.
MAX인 경우는,
SELECT name FROM rooms ORDER BY name DESC LIMIT 1;
위의 SQL과 동일한 결과값이 출력됩니다.
AVG
컬럼의 평균값을 반환합니다.
SELECT avg(no_seats) FROM rooms;
no_seats의 평균을 구해보면,
48 ((72 + 36 + 36) / 3)이 출력되는 것을 확인할 수 있습니다.
그룹핑
집계함수를 사용하다보면, 한가지 문제점을 겪을 수 있는데 SUM 함수를 사용하면서 다른 컬럼을 SELECT에 추가하려고 하면 오류가 발생한다.
오류가 발생하는 이유로는, 여러행을 하나의 값으로 반환하는 집계함수와 다르게 일반 컬럼은 모든 행의 값을 출력할려고 하기 때문입니다.
이러한 문제를 해결하기 위해서 여러행을 묶어서 출력하는 그룹핑 기능을 사용해야합니다.
GROUP BY
GROUP BY절을 사용해서, 그룹핑 기능을 사용할 수 있습니다.
위와같은 rooms 테이블을 가지고 있다고 가정하겠습니다.
SELECT name, count(*) AS total FROM rooms;
name을 그룹핑해서 카운팅 하고 싶어서 위와같이 SQL을 작성하게 되면,
위와같이 GROUP BY없이 집계되지 않은 컬럼을 사용했다는 내용의 에러가 발생하게 됩니다.
SELECT name, count(*) AS total FROM rooms
GROUP BY name;
GROUP BY 절을 사용해서 name 컬럼을 그룹핑해주면,
위와같이 원하는 결과를 얻을 수 있습니다.
집계함수를 사용할 때, 별칭(AS)을 사용해서 원하는 컬럼명으로 변경하는 것이 가능합니다.
HAVING
HAVING절은 WHERE절 처럼 레코드를 필터링하고 싶은 경우에 사용을 하는데, GROUP BY를 통해 그룹핑해서 얻은 데이터를 필터링할 때 사용합니다. 따라서, GROUP BY를 사용한 경우에만 쓸 수 있습니다.
SELECT name, sum(no_seats) AS total FROM rooms
GROUP BY name;
name 별 no_seats 컬럼의 합을 확인해보면,
위와같은 결과를 얻을 수 있는데, 여기서 total 값이 40 이상인 결과만 얻고 싶으면,
SELECT name, sum(no_seats) AS total FROM rooms
GROUP BY name
HAVING total >= 40;
GROUP BY 다음에 HAVING 을 추가해주면 됩니다.
total이 35였던 B의 레코드가 제외된 것을 확인할 수 있습니다.
또한,
SELECT name, sum(no_seats) AS total FROM rooms
GROUP BY name
HAVING total >= 40
AND name = 'C';
HAVING절도 WHERE절과 마찬가지로 AND나 OR등을 사용하는 것이 가능합니다.
⚠️주의할 점
HAVING으로 필터링하는 것은 어디까지나 그룹핑해서 나온 결과 레코드를 대상으로 하는 필터링입니다.
따라서, HAVING을 통해서 SELECT에 포함되어있지 않은 다른 컬럼을 조건으로 사용하는 것은 불가능합니다.
다른 컬럼을 조건으로 사용하고 싶은 경우에는 기존의 WHERE절을 통해서 처리합니다.
'IT 공부 > DB' 카테고리의 다른 글
[ MySQL ] 외래키 설정으로 인한, 데이터 삭제 변경이 안되는 경우 해결 방법 3가지 (1) | 2024.07.09 |
---|---|
[ MySQL ]데이터베이스 문자열 함수 ( concat, substring, upper, lower) (0) | 2024.07.04 |
[DB] 데이터 베이스 정규화 (제 1 정규화, 제 2정규화, 제 3정규화) (0) | 2024.07.01 |
컬럼 수정하기 (제약조건, 컬럼명, 데이터 타입) (0) | 2024.06.24 |
[ DB ] LIKE 조건에 서브쿼리와 조인을 이용하는 방법 (0) | 2022.12.11 |