티스토리 뷰
각 행을 그룹으로 묶기 - GROUP BY
group by 는 공통적인 데이터별로 묶어서 연산처리를 하고싶을 때 사용합니다.
그렇게되면 그룹 별 하나의 결과값이 출력되겠죠?
쉽게 예를 들자면, 전체 회원 데이터에서
남-여 회원의 수,
나이대 별(20대-30대-40대) 회원 수
이럴 때, count 함수와 group by 를 함께 사용한답니다.
만약 회사에 3개의 '부서'가 있는데, '같은 부서'의 직원들끼리 묶어라. 라고 한다면
그룹이 3개 이므로 3개의 행이 출력됩니다.
여기서 '부서번호' 를 사용해서 같은 부서끼리 묶었으므로 (원래는 단일행이지만 group by 에 사용되었기 때문에)
select 절에서 그룹함수와 같이 사용이 가능합니다.
하지만, group by 에 사용된 컬럼 이외의 컬럼은 단독으로 select 절에 사용할 수 없습니다.
group by 에 사용된 컬럼만 select 절에 사용 가능하다는 것이죠!
추가적으로, group by 절에는 반드시 컬럼명이 와야하고, alias 는 사용이 불가합니다. alias는 무조건 orderby 절 에서만 사용 가능해요!
구문 순서에 대한 자세한 정보는
이것을 적용해보면,
부서별 급여 평균을 구한 결과입니다.
deptno(부서번호)는 단일행이지만 group by 에 사용되었으므로 select 절에 사용될 수 있다는 점!
참고해주시면 됩니다.
그룹을 2차 그룹으로 더 상세하게 묶을 수 있는데요.
이럴 경우 더 상세해진만큼 행이 늘어나게 된답니다.
다음 예는, 같은 부서 내의, 같은 직무별 급여 평균을 구한 결과입니다.
다음은, 부서별 최대 연봉 구하기입니다.
max, min 함수는 알파벳, 숫자, 문자 다 사용 가능하답니다!
=> 여기서 누가 최대 연봉을 받는지 알고 싶어서 ename을 쓰는 순간 오류가 발생합니다.
왜냐하면, ename 은 단일행이기 때문에!
추가적인 정보를 얻기 위해 join 이 필요한데, join 은 곧 배울꺼에요!
join 을 살짝 말씀드리면 group by 로 표현할 수 없던 데이터를 표현할 수 있는 아주 유능한 문법입니다.
성별, 몸무게 평균 구하기
가공된 정보도 group by 절에 사용 가능하다는 것!
그룹에 대한 조건 - HAVING
WHERE 절은 FROM으로부터 불러들여진 데이터에서 필요한 데이터만 뽑는다면,
having 은 group by 로 묶여진 그룹에 대해 필요한 데이터만 뽑는 구문입니다.
HAVING :: 그룹별, 그룹 조건
having 절을 적용해보면,
학년별 평균 키, 평균 키 170 이상의 학년만 출력
=> 여기서 원하는 결과는 "학년(그룹) 별 평균 키, 단 평균 170 이상의 학년" 라는 정보입니다.
그러므로 먼저 그룹을 만든 후 조건을 적용해야겠죠?
그룹에 대한 조건은 where 절이 아닌, having 절에 사용해야 합니다.
avg(height)는 group by 절이 수행된 이후에 수행해야하므로, where 절에 사용할 수 없는 것이죠.
where 절 -> group by 절 -> having 절 이 순서로 동작합니다.
SQL의 문법 순서는 정말 중요합니다.
학년별 평균 키, 2학년이 아닌 나머지 학년 추출
=> "group by 절의 결과를 토대로 조건을 걸고 싶을 때, having을 사용한다" 라고 생각하고,
모든 조건을 having 절에 사용하면 안된다는거죠!
=>
그룹함수가 아니면 where절에서 사용 가능하므로,
미리 제거될 수 있는 정보는 where절에서 먼저 제거하는 것이 더 좋은 성능을 가진답니다.
만일, 단일행 조건을 having 절에서 사용한다면 힘들게 다 그룹 지어놓으니까 제거하는 것과 같은 의미입니다.
반대로, 단일행 조건을 where 에서 사용하면 그룹짓지 않아도 되는 데이터들은 미리 제거한 후 효율적이게 그룹을 짓는 것이겠죠.
그렇다면 그룹핑의 부화를 줄여줄 수 있으므로 속도 측면에서도 굉장히 유리하겠죠?!
GROUP BY 사용 시 주의사항
여기부터는, JOIN 에 관련된 내용이 포함되어있는데, JOIN 에 대해서 잘 모르시다면
아래 링크를 참고해주세요!
주의사항 1. 중복될 수 없는 컬럼과 Grouping
PROFESSOR 테이블을 사용하여 각 교수별로 먼저 입사한 교수(선배교수)의 수 출력 + 교수의 입사 날짜
=> GROUP BY 를 사용하는 순간 컬럼 사용에 제한이 생깁니다. 사용하시다보면 많이 느끼실꺼에요.
그래서 그룹바이 사용 시 내가 필요한 정보에 따라 같은 그룹을 나타내더라도 컬럼을 2~4 씩 함께 쓸 수 있습니다.
다시말해, GROUP BY 에다가 내가 SELECT에 쓰고 싶은 컬럼을 함께 써주면 됩니다.
그러면 그룹바이의 표현을 넓혀줄 수 있겠죠?
단, 동명이인이 있는 경우, 만일 이름만 같고 뒤에 정보가 다르다면, 서로 다른 그룹으로 생성되어 괜찮겠지만
동명이인에 심지어 뒤의 정보까지 같은 경우, 다른 사람이 같은 그룹으로 묶이게되어 없는 사람이 될 수 있습니다.
사원번호 이름 입사일 급여 직책
1111 Aaron 1980/06/23 00:00:00, 400, 사원
1112 Aaron 1980/06/23 00:00:00, 400, 사원
즉, Name 컬럼은 중복 가능하기때문에, 중복이 생길 시 위험한 그룹핑 컬럼입니다.
그러므로 고유 식별자와 같이 중복될 수 없는
교수번호(profno), 학번, 사원번호와 같은 컬럼를 그룹핑 컬럼으로 지정하는게 좋습니다.
이렇게 해주면, group by 의 나머지 컬럼에 어떤 컬럼이 오더라도 중복이 되지 않겠죠?
PROFESSOR 테이블을 사용하여 같은 학과 내의 선배의 수 출력
=> 연결된 테이블의 모든 조건에 같은 방향으로 OUTER JOIN 을 설정해주어야합니다.
그렇지 않는다면,
한 쪽의 데이터가 Null 값을 갖거나 조건이 성립하지 않으면 정보가 생략되버립니다.
STUDENT 테이블을 사용하여 각 학년별로, 각 학생마다 본인보다 키가 큰 친구의 수를 출력
출력 시, 학생의 이름, 학번, 학년, 키와 함께 출력
=> Name을 기준으로 Grouping해도 되지만, 혹시나 데이터가 중복되는 동명이인이 있을 수 있으므로
Studno 학번을 기준으로 Grouping 한거! 보이시죠?
참고: KIC 캠퍼스 머신러닝기반의 빅데이터분석 양성과정
'SQL' 카테고리의 다른 글
[SQL] 조인의 모든 것 - Join, Cartesian Product, EQUI, Non-Equi, Outer, Sefl (4) | 2018.12.19 |
---|---|
[SQL] SQL 구문(문법) 순서 - select, from, where, group by, having, order by (8) | 2018.12.19 |
[SQL] 그룹 함수(카운트, 합, 평균, 최대, 최소) - COUNT, SUM, AVG, MAX, MIN (0) | 2018.12.19 |
[SQL] 조건문 - DECODE, CASE~WHEN~THEN (0) | 2018.12.19 |
[SQL] null 값 치환하기 - NVL, NVL2 (0) | 2018.12.18 |