오라클 COUNT 0 포함 - olakeul COUNT 0 poham

코딩 테스트에서 자주 나오는 SQL 문제이다.

 

SELECT a.ID AS PLACE_ID, a.NAME, COUNT(IFNULL(b.CNT, 0)) AS '개수'
FROM PLACES AS a LEFT OUTER JOIN PLACE_REVIEWS b
ON a.ID = b.PLACE_ID
ORDER BY a.ID

 

생각보다 간단해서 금방 해결될줄 알았지만....

데이터가 없는 경우 로우는 포함되지 않는 결과값이 나왔다.

 

 

null일 경우 0 처리를 하기 위해서는

SELECT a.ID AS PLACE_ID, a.NAME, IFNULL(b.CNT, 0) AS '개수'
FROM PLACES AS a LEFT OUTER JOIN (
    SELECT PLACE_ID, COUNT(*) AS CNT
    FROM PLACE_REVIEWS
    GROUP BY PLACE_ID
) AS b
ON a.ID = b.PLACE_ID
ORDER BY a.ID

서브 쿼리에서 COUNT를 구하는 작업을 선작업 후, 조인을 걸어야 된다.

그런 후 IFNULL 함수를 사용해서 0 처리를 하면 결과값이 잘 나온다.

 

 

참고 링크 : https://blogger.pe.kr/231

 

공유하기

게시글 관리

구독하기Hello World

저작자표시

'데이터베이스' 카테고리의 다른 글

MySQL rank 함수  (0)2020.08.04ERD 관계 해석해보기  (0)2019.06.16식별관계, 비식별관계  (0)2019.05.02Mysql 5.7 이후 버전 비밀번호 변경 방법  (0)2018.12.24데이터베이스 릴레이션 키 정리  (0)2018.11.30

오라클에서 날짜별로 건수를 집계하면 존재하는 날짜만 조회되고 존재하지 않는 날짜는 표시되지 않는다. 상황에 따라서 건수가 존재하는 않는 날짜도 "0"으로 조회 되어야 할 상황이 있다.

 

가상의 날짜뷰를 만들어서 아우터 조인을 하면 해당 날짜가 데이터에 존재하지 않는 날짜도 표시가 가능하다. 필요에 따라서 이런 케이스가 많다면 물리적인 테이블을 생성해 놓고 사용하는 방법도 있다.

오라클 COUNT 0 포함 - olakeul COUNT 0 poham
COUNT 함수 예시
문법

COUNT (*)
COUNT (DISTINCT | ALL ] expr )
return [NUMBER]

파라미터

expr 어떤 식 열 이름

리턴

그룹의 레코드 건수 행수를 돌려 보낸다.

조건

SQL에서만 사용 가능. (PL/SQL 등)

내용

COUNT 함수에 별표 (*)를 사용하면 그룹의 모든 레코드 수를 돌린다.
식 또는 열 이름을 지정하면 해당식이 NULL 값 것들을 카운트에 포함하지 않는다.
또한 DISTINCT를 지정하면 중복 된 값의 행을 계산에 포함하지 않는다.

많은 경우 GROUP BY 절 을 사용하지 않고 전체 행수를 취득하는 경우가 많은데, 그룹 단위의 행수를 구하는 것도 가능하다.

COUNT의 특징적인 사용 방법은 그룹화 된 그룹 수를 결정하는데 COUNT (COUNT (*))과 중첩하여 사용할 수도 있다.

주의

COUNT 함수 식을 지정했을 경우, 식의 값이 NULL 값 의 경우 "정의되지 않음"을 나타낸다. 

"정의되지 않음"은 존재하지 않는 것으로 다루어진다.

그러나 COUNT 함수는 NULL을 건수에 포함하는 데 특별한 별표 (*)를 사용하는 구문이 준비되어 있으며

NULL을 포함하여 행수를 취득 할 수 있다.


데이터가 한 건도없는 경우는 레코드가 선택되지 않았습니다 대신 0을 되돌린다.
그러나 group by 병용 및 분석 함수 COUNT의 경우 결과는 0이 아닌 레코드가 선택되지 않았습니다 이다.

예시
namedeptsalaryA관리부300,000B관리부400,000C개발부500,000D개발부500,000E개발부200,000F개발부NULL

COUNT (*)와 COUNT ( expr )와 COUNT ( DISTINCT expr )의 차이.

SQL> select  COUNT (*), COUNT (salary), COUNT ( distinct  salary)
  2 from count_sample;
 
  COUNT (*) COUNT (SALARY) COUNT (DISTINCTSALARY)
 ---------- ------------- --------------- ------ 
         6              5               4
namedeptsalaryCOUNT (*)COUNT (salary)COUNT(distinct salary)A관리부300,000111B관리부400,000222C개발부500,000333D개발부500,00044E개발부200,000554F개발부NULL6--결과--654

부문(dept) 별로 구하게 된다면 건수는

SQL> select  dept, COUNT (*), COUNT (salary) from count_sample group by  dept;
 
DEPT            COUNT (*) COUNT (SALARY)
 ------------ ---------- -------------
관리부                 2            2
개발부                 4            3

식을 사용하여 NULL로 변환한 경우 : 급여가 500,000 의 것은 건수에 포함시키지 않는다.
(NULLIF 함수는 이러한 사용하지 않고, WHERE 조건으로 기술하는 방법이 맞다.)

SQL> select  dept, COUNT ( nullif (salary 500000)), COUNT (null)
  2 from count_sample group by  dept;
 
DEPT          COUNT ( NULLIF (SALARY 500000)) COUNT (NULL)
 ------------ ------------------------ ---- -----------
관리부                             2                0
개발부                             1                0

부문별로 급여가 200,000 이하의 수를 카운트하는 예시

select  dept, COUNT (salary), count (*) from count_sample
where salary <= 200000 group by  dept;
 
DEPT	  COUNT (SALARY)  COUNT (*)
 -------- ------------- ---------- 
개발부                           1

부문별로 급여가 200,000 엔 이하의 수를 카운트하는 (그 2)
데이터로 존재하지 않지만 제조 부 라는 부서가 존재하는 경우에는 부서 목록 등의 외부 결합이 필요

select  dept, COUNT (salary), count (salary2), count (*) from (
   select  dept,
     case  when salary> 200000 then null else salary end salary,
     case  when lnnvl (salary <= 200000) then null else salary end salary2
  from count_sample
)
group by  dept;
 
DEPT	  COUNT (SALARY) COUNT (SALARY2)	 COUNT (*)
 -------- ------------- -------------- - --------
관리부      0                0              2
개발부      1                4               

조건별로 계산하는 예제

select  dept, trunc (salary / 1000), COUNT (salary)
from count_sample group by  dept, trunc (salary / 1000)
 order by  dept, trunc (salary / 1000);
 
DEPT	  TRUNC (SALARY / 1000) COUNT (SALARY)
 -------- ------------------ -------------
관리부 300 1
관리부 400 1
개발부 200 1
개발부 500 2
개발부 0

조건별로 계산 2 (COUNTIF 바람)

select  dept, 
   COUNT ( case  when salary> = 500000 then 'X'  else null end) "> = 500K" ,
   COUNT ( case  when salary> = 400000 and salary <500000 then 'X'  else null end) "400K" ,
   COUNT ( case  when salary> = 300000 and salary <400000 then 'X'  else null end) "300K" ,
   COUNT ( case  when salary> = 200000 and salary <300000 then 'X'  else null end) "200K" ,
  COUNT ( case when salary> = 100000 and salary <200000 then 'X'  else null end) "100K" ,
   COUNT ( case  when salary <100000 then 'X'  else null end) "<100K" ,
   COUNT ( case  when salary is null then ' X '  else null end) "NULL" 
from count_sample group by  dept;
 
DEPT> = 500K 400K 300K 200K 100K <100K NULL
------ ------ ------ ------ ------ ------ ------ ------
관리부 0 1 1 0 0 0 0
개발부 2 0 0 1 0 0 1

카운트 함수의 계산 = COUNT (COUNT (*))
부문별로 구분하면 여러 그룹화되어 있는지 ... (관리부와 개발부의 2 그룹)

SQL> select  COUNT ( COUNT (*)) from count_sample group by  dept;
 
COUNT ( COUNT (*))
 --------------- 
              2