SQL(쿼리)

COUNT 집계함수

취미툰 2020. 11. 11. 14:51
반응형

count는 해당 컬럼의 갯수를 구하는 집계함수입니다.

 

COUNT함수가 NULL 값을 어떻게 카운트하는지 보겠습니다.

 

count함수는 NULL을 0으로 카운트합니다. col2와 col3를 보면 NULL값이 2개,1개 들어있으므로 count결과값이 null값을 제외하고 나온것을 확인할 수 있습니다.

--NULL에 대한 COUNT

select 
count(col1) cnt_col1
, count(col2) cnt_col2
, count(col3) cnt_col3
from (
select 'A' col1, null col2, 'C' col3 from dual 
union all
select 'B' col1, null col2, null col3 from dual
);

CNT_COL1    CNT_COL2    CNT_COL3   
----------- ----------- -----------
          2           0           1

 

하지만 COUNT(*)는 로우 자체의 건수를 카운트하기 때문에 값이 NULL임에도 불구하고 2건이 있다고 결과가 나옵니다.

즉, COUNT(*)는 로우를 구성하는 컬럼이 모두 NULL이어도 1로 카운트합니다.

아우터-조인을 사용시 COUNT(*)과 COUNT(컬럼명)을 상황에 따라 적절히 사용해야 합니다.

--NULL에 대한 COUNT (count(*)과 비교)

select 
count(col1) cnt_col1
, count(*) cnt_all
from (
select null col1  from dual 
union all
select null col1 from dual
);

CNT_COL1    CNT_ALL    
----------- -----------
          0           2

 

중복을 제거한 COUNT

 

COUNT안에서도 DISTINCT를 사용하여 중복을 제거할 수 있습니다.

주문테이블에서 주문년월별 '고객 수'와 주문 건수를 구하는 SQL을 작성해봅니다.

여기서 고객 수는 중복되지 않도록 카운트해야 합니다.

 

--중복을 제거한 COUNT

select to_char(주문날짜,'YYYYMM') 주문년월
,count(distinct 고객_ID) 고객 수
,count(*) 주문 수
from 주문
where 주문날짜 >= to_date ('20170101','YYYYMMDD')
and 주문날짜 < to_date ('20170401','YYYYMMDD')
group by to_char(주문날짜,'YYYYMM')
order by to_char(주문날짜,'YYYYMM');

 

COUNT(DISTINCT)는 여러 컬럼을 동시에 사용할 수 없습니다. 만약에 주문상태와 지불유형의 조합에 대한 종류 수가 필요하면 아래 SQL 중 아래와 같이 작성해야 합니다.

 

--DISTINCT에 여러 컬럼 넣는 SQL

-방법 1) 2개의 컬럼을 파이프로 결합해 사용하기
select count(distinct ord_st||'-'||pay_tp)
from t_ord;


-방법 2) 인라인 뷰를 사용하기
select count(*)
from (
select distinct ord_st,pay_tp
from t_ord
);

HAVING

 

HAVING절은 GROUP BY가 수행된 결과 집합에 조건을 줄 때 사용합니다. WHERE 절과 같은 기능이라고 볼 수 있습니다.

HAVING의 위치는 GROUP BY 뒤 ORDER BY 앞에 위치하게 됩니다.

 

--고객ID,지불유형별 주문금액이 10000이상인 데이터만 조회

select 고객ID,지불유형, sum(주문금액) 주문금액 합
from 주문
group by 고객ID,지불유형
having sum(주문금액) >= 10000
order by sum(주문금액) asc;


HAVING조건은 인라인-뷰에 대한 WHERE절로도 대신할 수 있습니다. GROUP BY의 결과를 인라인-뷰로 처리하고 밖에서 WHERE절로 처리합니다.

 

--인라인 뷰로 HAVING 결과와 동일하게 쿼리 짜기

select t0.*
fromn
(select 고객ID,지불유형, sum(주문금액) 주문금액 합
from 주문
group by 고객ID,지불유형) t0
where t0.주문금액 합 >= 10000
order by t0.주문금액 합 asc;

 

반응형