다른 대부분의 데이터베이스 제품들과 마찬가지로
PostgreSQL에서도 집계
함수 (aggregate function)를 사용할
수 있습니다. 집계 함수란 입력이 여러개의 로우이고, 출력이 하나인
결과인 것을 말합니다. 테이블의 전체 로우 수를 구하는
count
, 평균(avg
),
총합(sum
), 최대값(max
),
최소값(min
) 등등이 이런 함수들 입니다.
다음은 최고 기온을 구하는 쿼리입니다:
SELECT max(temp_lo) FROM weather;
max ----- 46 (1 row)
여기서 이 최고 기온의 해당 도시가 무엇인지 알기 위해서 다음과 같이 생각할 수도 있겠지요:
SELECT city FROM weather WHERE temp_lo = max(temp_lo); 잘못된 구문
하지만, 윗 쿼리의 결과는 오류를 냅니다. 왜냐하면, WHERE
절 다음에는 집계 함수를 사용할 수 없기 때문입니다. (이렇게 되는
이유는 윗 예를 들어, max
함수 자체가
select를 하지 않으면 나올 수 없는 값이기 때문입니다) 이런 문제는
다음과 같은 서브쿼리
(subquery)로 풀어야지 원하는
결과를 볼 수 있습니다:
SELECT city FROM weather WHERE temp_lo = (SELECT max(temp_lo) FROM weather);
city --------------- San Francisco (1 row)
윗 구문에서 where 다음에 나오는 (select ....) 구문을 서브쿼리(subquery)라고 합니다. 하나의 쿼리에서 서브쿼리가 있으면, 서버는 먼저 서브쿼리를 처리하고, 그 결과를 서브쿼리가 있는 자리에 대치시키고 다시 쿼리를 합니다.
집계 함수는 일반적으로 GROUP BY
절과 함께
사용하면 보다 다양하고 유용한 결과를 볼 수 있습니다. 예를 들어
각 도시별 최고기온을 살펴보려면 다음과 같은 쿼리를 사용합니다:
SELECT city, max(temp_lo) FROM weather GROUP BY city;
city | max ---------------+----- Hayward | 37 San Francisco | 46 (2 rows)
여기서 윗 결과 가운데, 또 집계된 자료에 대해서 어떤 조건이 주어질 때는
HAVING
구문을 사용하지요:
SELECT city, max(temp_lo) FROM weather GROUP BY city HAVING max(temp_lo) < 40;
city | max ---------+----- Hayward | 37 (1 row)
이것은 각 도시별 최고 기온이 40(주, 아마 화씨일듯)도가 되지 않는
목록들을 보는 것입니다. 마지막으로 도시 이름이
“S
”로 시작하는 도시들 가운데서
위와 같은 조건에 일치하는 자료를 찾으려면 다음과 같은 쿼리가 사용됩니다:
SELECT city, max(temp_lo) FROM weather WHERE city LIKE 'S%' -- (1) GROUP BY city HAVING max(temp_lo) < 40;
집계 함수를 사용 할 때는 WHERE
절과
HAVING
절의 관계를 반드시 숙지하고
있어야합니다. WHERE
절은 조회할
집계되지 않은 자료에 대한 조건이고, HAVING
은
집계된 자료에 대한 조건입니다. 그래서, WHERE
절의
조건으로 HAVING
절이 사용될
수 없습니다. 일반적으로 HAVING
절
다음에는 집계 함수가 사용됩니다. 물론 더 깊게 이야기하면,
WHERE
다음에 HAVING
이
올 수 있고, HAVING
다음에 집계 함수가
오지 않을 수도 있습니다. 하지만, 이런 골치 아픈 부분에 대해서는
이곳에서 언급해야할 이유가 없을 것 같습니다. 여기서는 단지,
WHERE
다음에는 집계할 대상에 대한 조건이,
HAVING
다음에 그 자료를 집계한 값에 대한 조건을
사용한다는 것만 이해하시면 됩니다.
앞 예제에서, 집계 작업을 하지 않고, WHERE
을 이용해서, 특정 도시만 그 대상으로 할 수 있습니다. 이것은
HAVING
예약어를 사용하는 방식보다
성능이 좋습니다. 왜냐하면, WHERE
절을 이용해서
집계 작업 대상 자체에서 제외했기 때문입니다.