데이터 분석/SQL

[SQL] GROUP BY와 ORDER BY 같이 쓸때 주의할 점

된장찌개냠냠 2024. 5. 19. 23:51
반응형

GROUP BY와 ORDER BY절은 SQL문을 작성할 때 매우 많이 사용되는 구문입니다. 단, 이 2가지 절을 함께 사용할 때는 주의해야 할 점이 있는데요. 이번 포스팅에서는 GROUP BY절과 ORDER BY절을 함께 사용할 때 발생할 수 있는 문제점과 해결방법에 대해서 알아보겠습니다.

 

GROUP BY와 ORDER BY를 함께 사용하는 쿼리 예시

아래 코드를 한번 살펴보겠습니다. 각 부서별로 평균 급여를 계산하고, 평균 급여가 높은 순서대로 데이터를 출력하는 쿼리입니다.

SELECT department_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id
ORDER BY avg_salary DESC;

 

출력되는 결과는 아래와 같습니다.

| department_id | avg_salary |
|---------------|------------|
| 2             | 75000      |
| 1             | 70000      |
| 4             | 65000      |

 

이렇게 GROUP BY와 ORDER BY를 같이 사용하는 케이스는 꽤 자주 등장합니다. 그럼 어떤 경우에 문제가 발생할 수 있을까요?

 

 

GROUP BY, ORDER BY 함께 사용 시 주의사항

먼저 ORDER BY의 특징에 대해 살펴보겠습니다. 아래 쿼리를 보면 SELECT 절에 salary라는 컬럼이 포함되지 않았지만 ORDER BY 절에서 salary 컬럼을 사용했습니다. 그리고 이 SQL문은 정상적으로 실행되며 문제가 없는 쿼리입니다. 즉, ORDER BY 절에는 SELECT 절에 없는 컬럼을 사용할 수 있다는 것입니다.

SELECT department_id, employee_id, emp_name
FROM employees
ORDER BY salary DESC;

 

그런데 GROUP BY가 포함된 쿼리에서는 이야기가 달라집니다. 몇 가지 케이스를 통해 알아보겠습니다. 그에 앞서 짚고 넘어가야 할 내용이 있는데요.

GROUP BY 절이 포함된 SQL문의 SELECT 절에는 1) 그룹핑 기준 컬럼(비집계 컬럼)과 2) 집계 함수에 사용되는 컬럼이 있습니다. 예를 들어 아래와 같은 쿼리에서 그룹핑의 기준이 되는 department_id는 비집계 컬럼이며, 집계함수의 대상이 되는 emp_id는 집계 컬럼이 되겠죠.

SELECT department_id, COUNT(emp_id) AS employee_count
FROM employees
GROUP BY department_id;

 

이 차이점을 이해했다면 이제 케이스별로 하나씩 살펴보겠습니다.

 

1. SELECT 절과 GROUP BY 절에 없는 컬럼 사용

1) SELECT 없음, GROUP BY 없음, ORDER BY에 비집계 컬럼 사용하는 경우 (불가능)

SELECT department_id, COUNT(emp_id) AS employee_count
FROM employees
GROUP BY department_id
ORDER BY department_name; -- department_name은 SELECT 절에 없는 비집계 컬럼

 

위 예시에서 department_name은 SELECT와 GROUP BY절에 모두 존재하지 않는 컬럼입니다. 거기다 집계 함수에 활용된 컬럼도 아니므로 비집계 컬럼이라고 할 수 있죠. 이 경우 실행하면 오류를 발생시킵니다.

물론, MySQL에서 ONLY_FULL_GROUP_BY 모드를 해제하면 오류 없이 출력 가능하지만 의미있는 정보가 아닐 가능성이 높습니다. 이에 관해서는 group by와 only_full_group_by 모드 완벽 이해하기 포스팅을 참고해주세요.

 

 

2) SELECT 없음, GROUP BY 없음, ORDER BY에 집계 컬럼 사용하는 경우 (가능)

SELECT department_id, COUNT(emp_id) AS employee_count
FROM employees
GROUP BY department_id
ORDER BY avg(salary); -- avg(salary)는 집계 함수에 활용된 집계 컬럼

 

위 경우, ORDER BY 절에 사용된 avg(salary)는 SELECT와 GROUP BY 절에 모두 존재하지 않지만, 집계함수에 이용된 집계 컬럼입니다. 이 경우는 사용이 가능하며 정상적으로 쿼리 결과가 출력됩니다.

 

 

2. SELECT 절에는 있고 GROUP BY절에는 없는 컬럼 사용

1) SELECT 있음, GROUP BY 없음, ORDER BY에 비집계 컬럼 사용하는 경우 (불가능)

이 경우는 애초에 GROUP BY의 사용 조건을 충족하지 못합니다. SELECT 절에 그룹핑 컬럼(비집계 컬럼)이 들어가려면, 반드시 GROUP BY 절에도 그 컬럼을 포함해야 하기 때문이죠. 따라서, SELECT 절에만 존재하는 비집계 컬럼을 ORDER BY 절에 사용하는 케이스는 없다고 볼 수 있습니다. (참고: group by와 only_full_group_by 모드 완벽 이해하기)

 

2) SELECT 있음, GROUP BY 없음, ORDER BY에 집계 컬럼 사용하는 경우 (가능)

SELECT department_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id
ORDER BY avg_salary DESC;

 

이 경우 avg_salary는 SELECT 절에만 존재하는 집계 컬럼입니다. 이때 AVG(salary)라고 적어도 되지만, 컬럼 별칭을 사용해 avg_salary라고 작성했습니다. 컬럼 별칭은 where 절에서는 사용이 불가하지만 order by 절에서는 사용이 가능합니다. (관련해서는 다음 포스팅을 참고해주세요: SQL 오래 사용해도 착각하기 쉬운 3가지)

쿼리를 실행하면 아래와 같이 정상적으로 출력되며 정확하게 활용한 사례라고 볼 수 있습니다.

| department_id | avg_salary |
|---------------|------------|
| 2             | 75000      |
| 1             | 70000      |
| 3             | 65000      |

 

 

3. GROUP BY 절에만 있는 컬럼 사용

1) SELECT 없음, GROUP BY 있음, ORDER BY에 비집계 컬럼 사용하는 경우 (가능)

이 경우도 정상적으로 쿼리가 실행됩니다. 단, 그룹핑 기준을 따로 표시하지 않을 이유는 크게 없을 것 같으므로, 자주 사용할 것 같지는 않습니다.

SELECT AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id
ORDER BY department_id;

 

2) SELECT 없음, GROUP BY 있음, ORDER BY에 집계 컬럼 사용하는 경우 (불가능)

GROUP BY 절에 직접 집계함수를 사용하는 것은 불가하므로 애초에 존재하지 않는 케이스입니다.

 

4. SELECT와 GROUP BY 모두에 있는 경우

1) SELECT 있음, GROUP BY 있음, ORDER BY에 비집계 컬럼 사용하는 경우 (가능)

아래 코드에서 department_name은 SELECT, GROUP BY, ORDER BY 절에 모두 존재합니다.

SELECT department_id, department_name, COUNT(*) AS employee_count
FROM employees
GROUP BY department_id, department_name
ORDER BY department_name;

 

위 쿼리 역시 정상적으로 실행되며, 아래와 같은 결과(예시)를 출력합니다.

| department_id | department_name | employee_count |
|---------------|-----------------|----------------|
| 3             | HR              | 5              |
| 2             | IT              | 7              |
| 1             | Sales           | 10             |

 

2) SELECT 있음, GROUP BY 있음, ORDER BY에 집계 컬럼 사용하는 경우 (불가능)

이 경우도 GROUP BY 절에 집계 함수가 들어가 있는 경우이므로 성립하지 않는 케이스입니다.

 

 

지금까지 GROUP BY 절과 ORDER BY 절을 동시에 사용하려고 할 때, 어떤 케이스에서 사용이 가능/불가능한지 알아보았습니다.

반응형