반응형
Group by(1)에서는 컬럼 하나에 대해서 정리를 했는데,
Group by(2) 에서는 컬럼 두가지가 group by 되는 과정을 정리해보자
- GROUP BY 절 Syntax
GROUP BY
{
column-Name [ , column-Name ]* | ROLLUP ( column-Name [ , column-Name ]* )
}
어김없이 나오는 Syntax
- 테스트할 때 사용한 데이터
SELECT * FROM EMP ORDER BY DEPTNO;
EMPNO|ENAME |JOB |MGR |HIREDATE |SAL |COMM|DEPTNO|
-----+---------+---------+----+-----------------------+----+----+------+
7934|MILLER |CLERK |7782|1982-01-23 00:00:00.000|1300| | 10|
7839|KING |PRESIDENT| |1981-11-17 00:00:00.000|5000| | 10|
7782|CLARK |MANAGER |7839|1981-06-09 00:00:00.000|2450| | 10|
7902|FORD |ANALYST |7566|1981-12-03 00:00:00.000|3000| | 20|
7566|JONES |MANAGER |7839|1981-04-02 00:00:00.000|2975| | 20|
7369|SMITH |CLERK |7902|1980-12-17 00:00:00.000| 800| | 20|
7900|JAMES |CLERK |7698|1981-12-03 00:00:00.000| 950| | 30|
7844|TURNER |SALESMAN |7698|1981-09-08 00:00:00.000|1500| 0| 30|
7698|BLAKE |MANAGER |7839|1981-05-01 00:00:00.000|2850| | 30|
7654|MARTIN |SALESMAN |7698|1981-09-28 00:00:00.000|1250|1400| 30|
7521|WARD |SALESMAN |7698|1981-02-22 00:00:00.000|1250| 500| 30|
7499|ALLEN |SALESMAN |7698|1981-02-20 00:00:00.000|1600| 300| 30|
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|
------------------------------------------------------------------------
SELECT * FROM DEPT;
DEPTNO|DNAME |LOC |
------+-----------+--------+
10|ACCOUNTING |NEW YORK|
20|RESEARCH |DALLAS |
30|SALES |CHICAGO |
40|OPERATIONS |BOSTON |
50|DEVELOPMENT|KOREA |
DEPT 테이블과, EMP 테이블을 사용함, 기존 SCOTT스키마에 있는거 데이터 조금 추가해서 사용했습니다
- 각 부서의 연도별 입사자 수를 구해보자
SELECT B.DNAME "부서"
, TO_CHAR(HIREDATE,'YYYY')|| '년' "입사년도"
, COUNT(EMPNO) "총 입사자"
FROM EMP A
, DEPT B
WHERE A.DEPTNO = B.DEPTNO
GROUP BY B.DNAME , TO_CHAR(HIREDATE,'YYYY')
ORDER BY DNAME;
부서 |입사년도 |총 입사자|
-----------+--------+---------+
ACCOUNTING |1981년 | 2|
ACCOUNTING |1982년 | 1|
DEVELOPMENT|1993년 | 5|
DEVELOPMENT|1994년 | 2|
RESEARCH |1980년 | 1|
RESEARCH |1981년 | 2|
SALES |1981년 | 6|
뜬금 없지만 , EMP와 DEPT를 조인해서 해당부서의 입사년도별 입사자 수를 구하는 쿼리였다. 이것만 봐서 이해가 힘들다.
아래 내용을 한번 살펴보자
- GROUP BY 를 쉽게 이해해보자
SELECT DEPTNO, TO_CHAR(HIREDATE ,'YYYY') AS HIREDATE FROM EMP ORDER BY DEPTNO;
DEPTNO|HIREDATE|
------+--------+
10| 1982|
10| 1981|
10| 1981|
20| 1981|
20| 1981|
20| 1980|
30| 1981|
30| 1981|
30| 1981|
30| 1981|
30| 1981|
30| 1981|
50| 1993|
50| 1993|
50| 1993|
50| 1993|
50| 1993|
50| 1994|
50| 1994|
/*
GROUP BY처리하는 두 가지 컬럼만 출력한 이유는 GROUP BY 로 지정하지 않은
컬럼은 사용못하고 집계함수로 처리해야 사용 가능하다
*/
GROUP BY COL1, COL2.... 에서 사용한 컬럼은 그대로 SELECT 절에서 사용할 수 있지만, GROUP BY 절에 사용하지 않은 컬럼은 집계함수로 처리해야한다. 또한 위에 HIREDATE컬럼은 TO_CHAR로 타입변경과 YYYY로 포맷을 변경했는데, SELECT 절에서도 GROUP BY에서 가공한 컬럼을 그대로 사용해야한다.
만약 DEPTNO = 10이고, HIREDATE 입사년도가 1983년인 데이터가 추가로 INSERT되면,
DEPTNO 컬럼이 10일 때, HIREDATE 는 1981, 1982, 1983 세 가지 경우가 나온다.
아래와 같이 나올 것 이다.
DEPTNO|HIREDATE|
------+--------+
10| 1982|
10| 1981|
10| 1981|
10| 1983|
- 처리과정
0. 예를들어서 연도별 입사자 수 확인하는 쿼리를 짜야할 때
1. 처음 FULL TABLE ACCESS
SELECT * FROM EMP;
-- 전체 테이블 레코드를 가져옴!
2. GROUP BY DEPTNO, TO_CHAR(HIREDATE,'YYYY') 그룹바이 처리대상 확인
SELECT DEPTNO
, TO_CHAR(HIREDATE ,'YYYY') AS HIREDATE
, EMPNO
, ENAME
, JOB
, SAL
, COMM
, MGR
FROM EMP
ORDER BY DEPTNO;
|---GROUP BY---|-------------- 집계함수처리 ------------|
DEPTNO|HIREDATE|EMPNO|ENAME |JOB |SAL |COMM|MGR |
------+--------+-----+---------+---------+----+----+----+
10| 1982| 7934|MILLER |CLERK |1300| |7782|
10| 1981| 7839|KING |PRESIDENT|5000| | |
10| 1981| 7782|CLARK |MANAGER |2450| |7839|
20| 1981| 7902|FORD |ANALYST |3000| |7566|
20| 1981| 7566|JONES |MANAGER |2975| |7839|
20| 1980| 7369|SMITH |CLERK | 800| |7902|
30| 1981| 7900|JAMES |CLERK | 950| |7698|
30| 1981| 7844|TURNER |SALESMAN |1500| 0|7698|
30| 1981| 7698|BLAKE |MANAGER |2850| |7839|
30| 1981| 7654|MARTIN |SALESMAN |1250|1400|7698|
30| 1981| 7521|WARD |SALESMAN |1250| 500|7698|
30| 1981| 7499|ALLEN |SALESMAN |1600| 300|7698|
50| 1993| 8000|JEONG SEO|MANAGER |3500| |7839|
50| 1993| 8001|CHANG SUP|DEVELOPER|3500| |8000|
50| 1993| 8002|JE UK SEO|DEVELOPER|2900| |8000|
50| 1993| 8003|GU RI |DEVELOPER|2800| |8000|
50| 1993| 8004|GO TAE |DEVELOPER|2500| |8000|
50| 1994| 8005|YOUNG JAE|DEVELOPER|2100| |8000|
50| 1994| 8006|JU PARK |DEVELOPER|2100| |8000|
3. 결과
SELECT DEPTNO
, TO_CHAR(HIREDATE,'YYYY')
, COUNT(DEPTNO)
FROM EMP
GROUP BY DEPTNO, TO_CHAR(HIREDATE,'YYYY')
ORDER BY DEPTNO;
/*
GROUP BY TO_CHAR(HIREDATE, 'YYYY')로 YYYY포맷으로 변환 시
SELECT 절에서도 포맷을 맞춰줘야함
*/
DEPTNO|TO_CHAR(HIREDATE,'YYYY')|COUNT(DEPTNO)|
------+------------------------+-------------+
10|1981 | 2|
10|1982 | 1|
20|1980 | 1|
20|1981 | 2|
30|1981 | 6|
50|1993 | 5|
50|1994 | 2|
/*
GROUP BY 를 TO_CHAR(HIREDATE,'YYYY')으로 그룹핑을 해줬기 때문에 SELECT 절에서
GROUP BY와 다르게 TO_CHAR(HIREDATE, 'YYYY')처리를 하지 않으면 에러가 난다!
SELECT DEPTNO
, HIREDATE
, COUNT(DEPTNO)
FROM EMP
GROUP BY DEPTNO, TO_CHAR(HIREDATE,'YYYY')
ORDER BY DEPTNO;
Error!
SQL Error [979] [42000]: ORA-00979: GROUP BY 표현식이 아닙니다.
*/
GROUP BY 처리하는 DEPTNO와 HIREDATE 컬럼을 제외하고, 나머지컬럼은 집계함수로 처리할 것이니 GRUOPING 하는 컬럼만 확인하면 된다! 그룹핑처리하는 컬럼만 확인 후 나머지 컬럼은 집계함수로 COUNT, MAX, MIN, SUM 등등 집계함수로 처리해야 에러가 나지 않는다
반응형
'❌이전글 > 이전글' 카테고리의 다른 글
Java - String, new String() (3) | 2022.12.26 |
---|---|
윈도우11 - 무선(블루투스)이어폰 출력장치 없음, 이어폰 소리 안나옴 (3) | 2022.12.26 |
디비버(DBeaver) - ALIAS 자동완성 끄기 (0) | 2022.12.08 |
Oracle - decode()함수 정리 (0) | 2022.09.13 |
ORACLE - 그룹 바이(GROUP BY) (1) (0) | 2022.06.07 |
오라클(ORACLE) - FULL OUTER JOIN ANSI에서 오라클로 변환 (0) | 2022.04.03 |
DBeaver 공백이있는 쿼리 실행오류! (1) | 2021.12.22 |
DBeaver : no active connection 대체 뭐야.....? (4) | 2021.12.05 |