본문 바로가기

데이터베이스/SQL & PL/SQL

[SQL] DISTINCT & ALL, 중복 제거!


DISTINCT


 우선, SELECT문을 다음과 같이 작성, 실행시켜 봅니다.
SELECT emp.department_id, dep.department_name
FROM hr.employees emp INNER JOIN hr.departments dep
ON emp.department_id=dep.department_id;

제가 이 쿼리에서 알고 싶은것은 employees 테이블에서 사원들이 속해있는 모든 부서아이디와 부서명 입니다.

[실행화면]



-전체 결과의 일부입니다.

쿼리를 실행했더니 위와 같은걸 확인해 볼 수 있는데요, 문제는 중복된 데이터가 여러개 존재한다는 것입니다.
쉽게 얘기하면 사원들 각각의 데이터를 조회했다고 할 수 있겠네요. 우리는 그저 부서 아이디와 부서명을 알고 싶은데 말이죠.

 그럼 어떻게 해야 중복없이 우리가 원하는 결과를 얻을 수 있을까요?

 이 중복과 관련된 키워드가 바로 DISTINCT 와 ALL 입니다.
우선, ALL은 디폴트(Default)로서 명시하지 않아도 적용되는 반면, -참고로 위처럼 중복된 결과가 나오는 상태를 말합니다. 그렇기 때문에 굳이 신경안쓰셔도 되는 키워드 입니다. 반대로 'DISTINCT'를 명시해주게 되면, 중복된 값들이 하나의 값(nonduplicate values)으로 출력이 되게 됩니다.

 그렇다면 한번 중복성을 없애볼까요? 다음의 쿼리를 실행합니다.

SELECT DISTINCT emp.department_id, dep.department_name
FROM hr.employees emp INNER JOIN hr.departments dep
ON emp.department_id=dep.department_id;

[실행화면]

 중복된 값이 없이 제대로 원하는 결과가 나오는군요! 사원들이 속해 있는 부서는 총 11개의 부서로 위와 같이 존재함을 알 수 있습니다.
DISTINCT 중요한 키워드이니 잘 사용하시길 바랍니다 ^^.

 참고로 정렬된 값을 얻으실려면 ORDER BY 절을 쓰시면 됩니다. 오라클 9I버전때까지는 'DINTINCT'를 쓰게 되면 정렬되서 나왔는데, 성능문제로 이후 버전에서는 정렬되서 나오지 않습니다.

집계함수에서의 DISTINCT


 집계(그룹)함수에 대해서는 이미 다른글에서 다루었기 때문에 그에 대한 내용은 생략하겠습니다.
혹시 관련된 글을 참고하실 분들은 아래의 링크를 확인하시면 되겠습니다.
그룹(집계)함수 글 확인하기


 우선, 모든 집계함수(AVG, COUNT, MAX, MIN,STDDEV, SUM VARIANCE) 에 대해서 'DISTINCT' 사용이 가능합니다.

 위의 섹션과 관련 높은 것으로 다음 예제를 볼 수 있습니다. 집계함수 중 COUNT를 써서 사원들이 속하는 부서가 얼마나 존재하는지 알아보겠습니다. 
SELECT COUNT(department_id)
FROM hr.employees;

[실행화면]

 결과는 106개의 부서가 조회되는 군요. 결과만 미루어 봤을때는 중복성이 배제가 되지 않은채 글의 맨 윗 쿼리처럼 결과가 나온 것으로 추측할 수 있습니다. 그렇다면 중복성 배제를 위해서 집계함수에서는 어떻게 해야 할까요? 맞습니다. 함수 안에 'DISTINCT'를 명시해주면 됩니다. 
SELECT COUNT(DISTINCT department_id)
FROM hr.employees;

[실행화면]

 11개의 부서로 원하는 결과를 얻었군요. 

 하나더 해볼까요? 다음의 두가지 결과를 비교해서 집계함수가 어떻게 적용되는지 살펴볼게요.


[실행화면]
1.


2.

 1번의 결과는 AVG 함수 안에 적용되는 'salary'컬럼은 'ALL'인 상태입니다. 그래서 평균을 낼때 모든 사원(107명)들이 고려되었다는 것을 COUNT 함수를 통해서 알수 있죠.

 2번의 결과는 DISTINCT를 적용한 것으로 AVG 함수가 적용될때, 중복성이 존재하는 값들을 제하고 COUNT 함수의 결과에서 볼수 있듯이 57개의 데이터로 평균값이 도출된 것을 알 수 있습니다. 여기서 말하는 중복 값의 제외란, 만일에 월급을 나와 똑같이 받는 사람들이 있다면 모두 제외했다는 말이 됩니다.
 


 참고로 덧붙여, 'GROUP BY' 에서와 'DISTINCT'가 출력하는 값이 똑같을 수 있지만, 'DISTINCT'는 값을 제외(!) 시키는데 반해, 'GROUP BY' 는 말그대로 값 생략없이 그룹화, 묶는다는 것에 주의를 하시면 될 것같습니다. 이상 입니다 ^^


도움 되셨다면 밑의 추천(손가락 표시)과 댓글 부탁드립니다.