이제 집계 함수 쓸 때 자주 나오는 실수들 좀 더 깊게 파볼 시간이야. 진짜 SQL 좀 한다는 사람들도 가끔씩 이런 실수 하거든. 우리 목표는 이런 함정들 미리 알아보고 잘 피해가는 거야.
쿼리 짜다가 "column must appear in the GROUP BY clause or be used in an aggregate function" 이런 이상한 에러 본 적 있어? 아니면 쿼리 결과가 뭔가 이상한데 왜 그런지 감도 안 잡힌 적? 이게 바로 집계 함수 쓸 때 흔히 만나는 실수들의 빙산의 일각이야. 이 강의는 그런 실수들 바다에서 살아남는 가이드라고 생각하면 돼.
실수 1: GROUP BY 밖에서 집계 안 한 컬럼 쓰기
문제
집계된 데이터 뽑으려고 쿼리 짰는데, 그룹핑에 안 들어가고 집계 함수도 안 씌운 컬럼을 추가했어. 예를 들면:
SELECT department, salary, SUM(salary)
FROM employees
GROUP BY department;
PostgreSQL이 바로 이렇게 말할 거야:
ERROR: column "employees.salary" must appear in the GROUP BY clause or be used in an aggregate function
왜 이런 일이 생길까?
GROUP BY 쓰면 PostgreSQL이 지정한 컬럼 기준으로 행을 묶어. 근데 거기에 다른 컬럼(salary)을 추가하면, PostgreSQL은 그걸 어떻게 처리해야 할지 모르는 거지. 한 명의 salary만 보여줄지, 평균을 낼지, 뭘 원하는지 알 수가 없으니까.
어떻게 고치냐면 두 가지 방법이 있어:
- 집계 안 한 컬럼은 전부
GROUP BY에 넣기:
SELECT department, salary
FROM employees
GROUP BY department, salary;
- 아니면 컬럼을 집계 함수로 감싸기(이게 더 맞는 경우):
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department;
팁: PostgreSQL이 GROUP BY 관련 에러 내면, "이 컬럼 진짜 쿼리에 필요한가? 필요하다면 무슨 역할이지?" 이렇게 한 번 더 생각해봐.
실수 2: COUNT()랑 NULL 헷갈리기
문제: 직원들 중에서 보너스 입력한 사람 수 세고 싶어서 이렇게 썼어:
SELECT COUNT(bonus) AS bonus_count
FROM employees;
근데 결과가 생각보다 적게 나와. 왜냐면 COUNT(column)은 column이 NULL인 행은 아예 무시하거든.
해결법: 모든 행을 세고 싶으면 COUNT(*) 써야 해:
SELECT COUNT(*) AS total_count
FROM employees;
아니면 보너스가 NULL 아닌 행만 세고 싶으면 이렇게:
SELECT COUNT(bonus) AS bonus_count
FROM employees
WHERE bonus IS NOT NULL;
팁: NULL 들어간 행이랑 테이블에 아예 없는 행 구분하고 싶으면 COUNT(*)랑 COUNT(column) 차이 잘 생각해서 써야 해.
실수 3: HAVING 대신 WHERE로 집계 결과 필터링
문제: 부서별로 평균 연봉이 5000 넘는 곳 찾고 싶어서, 초보 개발자가 이렇게 쓸 수도 있어:
SELECT department, AVG(salary) AS avg_salary
FROM employees
WHERE AVG(salary) > 5000
GROUP BY department;
PostgreSQL이 에러 뱉어:
ERROR: aggregate functions are not allowed in WHERE clause
이유는 WHERE는 먼저 실행되고, 집계 함수는 GROUP BY 이후에 계산되기 때문이야. 즉, AVG(salary)는 WHERE 단계에선 아직 계산이 안 됐거든.
이럴 땐 집계 결과 필터링은 HAVING으로 해야 해:
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING AVG(salary) > 5000;
실수 4: WHERE 위치 헷갈려서 실행 순서 꼬이기
문제: 30살 넘는 직원이 있는 부서별 인원수 알고 싶어서 이렇게 썼어:
SELECT department, COUNT(*)
FROM employees
GROUP BY department
WHERE age > 30;
PostgreSQL이 또 에러 내지:
ERROR: syntax error at or near "WHERE"
왜냐면 WHERE는 항상 GROUP BY보다 먼저 처리돼. 근데 여기선 WHERE 위치가 잘못된 거지.
이럴 땐 먼저 행을 필터링하고, 그다음에 그룹핑해야 해.
SELECT department, COUNT(*)
FROM employees
WHERE age > 30
GROUP BY department;
실수 5: SUM(), AVG() 등에서 NULL 처리 안 함
문제: 직원들한테 준 전체 보너스 합계 구하려고 이렇게 썼어:
SELECT SUM(bonus) AS total_bonus
FROM employees;
근데 결과가 너무 적게 나와. 왜냐면 직원 절반이 보너스 안 적어서 NULL인데, 이건 그냥 무시돼버려.
해결법: NULL을 미리 처리해줘야 해. 예를 들어 NULL을 0으로 바꿔서:
SELECT SUM(COALESCE(bonus, 0)) AS total_bonus
FROM employees;
이제 NULL은 전부 0으로 바뀌어서 합계가 제대로 나와.
COALESCE 함수는 곧 다음 강의에서 더 자세히 다룰 거야.
실수 6: 여러 집계 함수 쓸 때 각각 따로 노는 거 모름
문제: 전체 직원 수랑 전체 연봉 합계를 구하려고 했는데, 결과가 뭔가 이상해:
SELECT COUNT(salary) AS count_salary, SUM(salary) AS total_salary
FROM employees;
왜냐면 누군가 salary가 NULL이면 COUNT(salary)랑 SUM(salary) 결과가 달라져서 헷갈릴 수 있어.
집계 함수들은 서로 독립적으로 동작해. NULL 있으면 결과가 다르게 나올 수 있으니까, COALESCE나 COUNT(*) 써서 일관성 있게 만들어줘:
SELECT COUNT(*) AS total_employees, SUM(COALESCE(salary, 0)) AS total_salary
FROM employees;
실수 7: 너무 많은 컬럼으로 GROUP BY 해서 쿼리 느려짐
문제: 그룹핑 컬럼이 너무 많아서 쿼리 돌리면 5분이 아니라 5시간 걸리는 경우:
SELECT department, job_title, location, COUNT(*)
FROM employees
GROUP BY department, job_title, location;
그룹핑하기 전에 진짜 모든 컬럼이 GROUP BY에 필요한지 한 번 더 생각해봐. 그룹별로 값이 다양할수록 쿼리 느려지거든. 가능하면 그룹핑 컬럼 줄여보자:
SELECT department, COUNT(*)
FROM employees
GROUP BY department;
이런 실수들은 진짜 SQL 잘하는 개발자들도 종종 겪어. 이제 이런 함정들 좀 더 쉽게 피해가고, 빠르고, 정확하고, 예쁜 쿼리 짤 수 있을 거야!
GO TO FULL VERSION