그룹바이를 정리해보고 싶었다. 그래서 정리해봤다.
먼저 그룹바이를 알기 전 SQL 실행 순서를 알아야 한다고 배웠다.
- SQL 실행 순서
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY
- Group by 란?
- 데이터를 그룹화하는 문법, 값은 값을 가진 데이터끼리 모으는 것
- GROUP BY 컬럼이 아니면 집계함수로 표현해야한다
- GROUP BY 컬럼이 아니면 SELECT 절에서 집계함수를 사용하지 않으면 에러가 난다
SELECT *
FROM EMP
GROUP BY DEPTNO
----------------
SQL Error [979] [42000]: ORA-00979: GROUP BY 표현식이 아닙니다.
- 테스트에 사용한 데이터
오라클에서 주는 SCOTT스키마를 사용하였고, 테이블은 EMP 테이블에 멋대로 아무거나 넣었다.
SELECT * FROM EMP;
EMPNO|ENAME |JOB |MGR |HIREDATE |SAL |COMM|DEPTNO|
-----+---------+---------+----+-----------------------+----+----+------+
7369|SMITH |CLERK |7902|1980-12-17 00:00:00.000| 800| | 20|
7499|ALLEN |SALESMAN |7698|1981-02-20 00:00:00.000|1600| 300| 30|
7521|WARD |SALESMAN |7698|1981-02-22 00:00:00.000|1250| 500| 30|
7566|JONES |MANAGER |7839|1981-04-02 00:00:00.000|2975| | 20|
7654|MARTIN |SALESMAN |7698|1981-09-28 00:00:00.000|1250|1400| 30|
7698|BLAKE |MANAGER |7839|1981-05-01 00:00:00.000|2850| | 30|
7782|CLARK |MANAGER |7839|1981-06-09 00:00:00.000|2450| | 10|
7839|KING |PRESIDENT| |1981-11-17 00:00:00.000|5000| | 10|
7844|TURNER |SALESMAN |7698|1981-09-08 00:00:00.000|1500| 0| 30|
7900|JAMES |CLERK |7698|1981-12-03 00:00:00.000| 950| | 30|
7902|FORD |ANALYST |7566|1981-12-03 00:00:00.000|3000| | 20|
7934|MILLER |CLERK |7782|1982-01-23 00:00:00.000|1300| | 10|
8000|JEONG SEO|MANAGER |7839|1993-08-27 00:00:00.000|3500| | 50|
8001|CHANG SUP|DEVELOPER|8000|1993-08-28 00:00:00.000|3500| | 50|
8002|JE UK SEO|DEVELOPER|8000|1993-08-29 00:00:00.000|2900| | 50|
8003|GU RI |DEVELOPER|8000|1993-08-30 00:00:00.000|2800| | 50|
8004|GO TAE |DEVELOPER|8000|1993-09-01 00:00:00.000|2500| | 50|
8005|YOUNG JAE|DEVELOPER|8000|1994-02-07 00:00:00.000|2100| | 50|
8006|JU PARK |DEVELOPER|8000|1994-02-07 00:00:00.000|2100| | 50|
- GROUP BY 절
GROUP BY
{
column-Name [ , column-Name ]* | ROLLUP ( column-Name [ , column-Name ]* )
}
오라클 문서에서 찾아보니 syntax는 위와 같았다.
- GROUP BY ()
SELECT MAX(DEPTNO)
FROM EMP
GROUP BY ();
MAX(DEPTNO)|
-----------+
50|
GROUP BY 뒤에 () 괄호기호를 사용하면 전체 출력되는 행이 하나의 그룹으로 인식됨, 하나의 그룹으로 잡고 MAX값으로 50이 출력
- GROUP BY() 실행계획
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 19 | 247 | 4 (25)| 00:00:01 |
| 1 | HASH GROUP BY | | 19 | 247 | 4 (25)| 00:00:01 |
| 2 | TABLE ACCESS FULL| EMP | 19 | 247 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------
혹시나 해서 실행계획을 봤다. 딱히 뭐 없었다. 그냥 TABLE ACCESS FULL로 19행을 가져오고 그룹바이 처리하는 실행계획이었다. 아래와 같이 처리되는 게 아닐까??
// 모든 출력 데이터는 위에 적어놨고 전체 건수만 표시해주기위해, 결과와 다른 값을 적
// 어 놨습니다.
// 아래 결과가 나오려면 SELECT COUNT(1) FROM EMP; 입니다.
(1) SELECT * FROM EMP;
COUNT(1)|
--------+
19|
(2) SELECT MAX(DEPTNO) FROM EMP GROUP BY ()
DEPTNO|
------+
50|
- GROUP BY column
이번엔 GROUP BY 뒤에 한개의 컬럼을 넣고 그룹핑을 해보자!
SELECT DEPTNO, SUM(SAL)
FROM EMP
GROUP BY DEPTNO;
DEPTNO|SUM(SAL)|
------+--------+
50| 19400|
30| 9400|
10| 8750|
20| 6775|
SELECT * FROM EMP; 로 19건을 가져오는데 거기서 중복되는 DEPTNO (부서코드) 를 하나로 그룹핑하고 SAL을 SUM()함수 처리한 결과이다.
- GROUP BY (그룹바이) 그룹핑 처리
그룹핑되는 걸 대충 정리해봤다.
SELECT DEPTNO, SUM(SAL)
FROM EMP
WHERE DEPTNO = 10
GROUP BY DEPTNO
DEPTNO|SUM(SAL)|
------+--------+
10| 8750|
해당 쿼리와 결과값이다.
EMP 테이블에서 DEPTNO 값이 10인 녀석들을 가져오고 DEPTNO를 GROUP BY로 그룹핑하는 쿼리다
1. TABLE ACCESS FULL 테이블에 ACCESS해서 데이터를 가져오자!
2. GROUP BY DEPTNO로 그룹핑을 하자!
3. SELECT 절을 처리하자!
대충 위와 같은 순서로 처리되는 게 아닐까? 시간 나면 GROUP BY column1, column2 , HAVING 도 보기 편하게 정리해봐야겠다.
※참고
https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqlj32654.html
불친절한 SQL프로그래밍
'❌이전글 > 이전글' 카테고리의 다른 글
윈도우11 - 무선(블루투스)이어폰 출력장치 없음, 이어폰 소리 안나옴 (3) | 2022.12.26 |
---|---|
디비버(DBeaver) - ALIAS 자동완성 끄기 (0) | 2022.12.08 |
Oracle - decode()함수 정리 (0) | 2022.09.13 |
ORACLE - 그룹 바이(GROUP BY) (2) (2) | 2022.06.12 |
오라클(ORACLE) - FULL OUTER JOIN ANSI에서 오라클로 변환 (0) | 2022.04.03 |
DBeaver 공백이있는 쿼리 실행오류! (1) | 2021.12.22 |
DBeaver : no active connection 대체 뭐야.....? (4) | 2021.12.05 |
오라클 한글 3byte -> 2byte변경 (0) | 2021.11.20 |