SQL - Group by

이재용·2025년 1월 1일
0

group by절에 기술된 컬럼값으로 반드시 1의 집합을 가지게 됨(컬럼이 유니크해짐).
select절에는 group by절에 기술된 컬럼집계함수만 사용될 수 있음.

집계함수(Aggregate Function)

  • count, sum, avg, max, min
    집계함수는 Null을 계산하지 않음
    max, min의 경우 문자열, 날짜/시간형에도 쓸 수 있다. 소문자영문이 가장 큰 값(유니코드)
    count 주의점
  • count(*) == count(1) == count(2) == count(0) -> 정해진 집합 레벨에서 데이터 건수를 가져옴
  • count(distinct 컬럼명) -> 정해진 집합 레벨에서 해당 컬럼으로 중복을 배제하고 고유한 건수를 가져옴
    예제
부서명 SALES와 RESEARCH 소속직원별로 과거부터 현재까지 모든 급여를 취합한 평균 급여
select b.empno, max(b.ename) as ename, avg(c.sal) as avg_sal
from hr.dept a
	join hr.emp b on a.deptno = b.deptno
	join hr.emp_salary_hist c on b.empno = c.empno
where a.dname in('SALES', 'RESEARCH')
group by b.empno;

job이 SALESMAN인 경우와 그렇지 않은 경우만 나누어서 평균/최소/최대 급여를 구하기.
select case when job = 'SALESMAN' then 'SALESMAN'
		else 'OTHERS' end as job_gubun
		, avg(sal) as avg_sal
		, max(sal) as max_sal, min(sal) as min_sal
		, count(*)
from hr.emp
group by case when job = 'SALESMAN' then 'SALESMAN'
		else 'OTHERS' end;

Pivoting

deptno로 group by하고 job으로 pivoting
select sum(case when job = 'SALESMAN' then sal end) as sales_sum
	, sum(case when job = 'MANAGER' then sal end) as manager_sum
	, sum(case when job = 'ANALYST' then sal end) as analyst_sum
	, sum(case when job = 'CLERK' then sal end) as clerk_sum
	, sum(case when job = 'PRESIDENT' then sal end) as president_sum
from emp;

-group by Pivoting시 조건에 따른 건수 계산 시 sum()을 이용
select deptno, count(*) as cnt
    , sum(case when job = 'SALESMAN' then 1 else 0 end) as sales_cnt
    , sum(case when job = 'MANAGER' then 1 else 0 end) as manager_cnt
    , sum(case when job = 'ANALYST' then 1 else 0 end) as analyst_cnt
    , sum(case when job = 'CLERK' then 1 else 0 end) as clerk_cnt
    , sum(case when job = 'PRESIDENT' then 1 else 0 end) as president_cnt
from emp
group by deptno;

Rollup

Group by 시 Rollup을 함께 사용하면 Rollup에 적용된 순서대로 계층적인 Group by를 추가적으로 수행

++일별 매출합 구하기
월 또는 일을 01, 02와 같은 형태로 표시하려면 to_char()함수, 1, 2와 같은 숫자값으로 표시하려면 date_part()함수 사용.
select to_char(b.order_date, 'yyyy') as year
	,to_char(b.order_date, 'mm') as month
	,to_char(b.order_date, 'dd') as day
	,sum(a.amount)
from nw.order_items a
	join nw.orders b on a.order_id = b.order_id
group by rollup (to_char(b.order_date, 'yyyy'), to_char(b.order_date, 'mm'), to_char(b.order_date, 'dd'))
order by 1,2,3

0개의 댓글