다른 대부분의 데이터베이스 제품들과 마찬가지로 PostgreSQL에서도 집계 함수(aggregate function)를 사용할 수 있습니다. 집계 함수란 입력이 여러개의 row이고, 출력이 하나인 결과인 것을 말합니다. 테이블의 전체 row 수를 구하는 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를 하지 않으면 나올 수 없는 값이기 때문입니다) 이런 문제는 다음과 같은 쿼리로 풀어야지 원하는 결과를 볼 수 있습니다:
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%'
GROUP BY city
HAVING max(temp_lo) < 40;
- LIKE 연산자는 패턴 매칭 관련 연산자인데, 자세한 것은 사용자 안내서를 참조하십시오.
- 집계 함수를 사용 할 때는 where 절과 having 절의 관계를 반드시 숙지하고 있어야합니다. where 절은 조회할 집계되지 않은 자료에 대한 조건이고, having은 집계된 자료에 대한 조건입니다. 그래서, where 절의 조건으로 having 절이 사용될 수 없습니다. 일반적으로 having 절 다음에는 집계함수가 사용됩니다. 물론 더 깊게 이야기하면, where 다음에 having이 올 수 있고, having 다음에 집계 함수가 오지 않을 수도 있습니다. 하지만, 이런 골치 아픈 부분에 대해서는 이곳에서 언급해야할 이유가 없을 것 같습니다. 여기서는 단지, where 다음에는 집계할 대상에 대한 조건이, having 다음에 그 자료를 집계한 값에 대한 조건을 사용한다는 것만 이해하시면 됩니다.
(주, 집계 함수를 유연하게 사용한다면 보고서 작성과 응용프로그램의 코딩에 엄청난 도움을 줍니다. select 구문에서 join과 함께 제일 까다로운 부분이기도 하지만 잘 숙지하셔서 유용하게 사용하시길)