티스토리 뷰

반응형

각 행을 그룹으로 묶기 - 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 로 묶여진 그룹에 대해 필요한 데이터만 뽑는 구문입니다. 

 

WHERE :: 행별, 개별 조건

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 의 나머지 컬럼에 어떤 컬럼이 오더라도 중복이 되지 않겠죠?

 

 


 주의사항 2. 아우터 조인 시 연결 테이블에 모두 표현!

 PROFESSOR 테이블을 사용하여 같은 학과 내의 선배의 수 출력

 => 연결된 테이블의 모든 조건에 같은 방향으로 OUTER JOIN 을 설정해주어야합니다. 

      그렇지 않는다면, 

      한 쪽의 데이터가 Null 값을 갖거나 조건이 성립하지 않으면 정보가 생략되버립니다.



   STUDENT 테이블을 사용하여 각 학년별로, 각 학생마다 본인보다 키가 큰 친구의 수를 출력

   출력 시, 학생의 이름, 학번, 학년, 키와 함께 출력

 => Name을 기준으로 Grouping해도 되지만, 혹시나 데이터가 중복되는 동명이인이 있을 수 있으므로

      Studno 학번을 기준으로 Grouping 한거! 보이시죠?




참고: KIC 캠퍼스 머신러닝기반의 빅데이터분석 양성과정



반응형
댓글
최근에 올라온 글
최근에 달린 댓글
링크
Total
Today
Yesterday